gpt4 book ai didi

c++ - extern 和 extern "C"用于变量

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:03:56 31 4
gpt4 key购买 nike

我正在编写供 C 程序使用的 C++ 共享库。但是,我对 externextern "C" 有疑问。

考虑以下代码

我的头文件是这样的:

#ifdef __cplusplus      
extern "C" int global;
extern "C" int addnumbers(int a, int b);
#else
extern int global;
#endif

这很好用;我只需要声明

int global;

在我的 .cpp 或我的 .c 文件中。但是,我不明白的是:

extern "C"extern 有什么区别?我尝试注释掉 extern "C"int global 并且有效!为什么?

我知道 extern "C" 用于建立 C 链接。这就是为什么我有 extern "C"int addnumbers(int,int)。换句话说,如果我想编写一个在 C 程序中使用的 C++ 函数,我会编写 extern "C"。现在,全局变量怎么样——我猜这里的情况有所不同?我希望 C 程序使用名为 global 的 C++ 变量,但我可以使用 extern 而不是 extern "C"。这是为什么?这对我来说不直观。

评论:我不认为这是重复的,因为我想问的是将它用于变量和函数时有什么区别。

最佳答案

通过将 extern "C" 附加到您的 C++ 声明(类似对象和函数),您为它们提供了“C 链接”- 使它们可以从 C 代码访问。如果省略此“语言链接”规范,则编译器不会做任何努力来进行正确的链接。在函数的情况下,这会导致链接失败,因为 mangling。在全局变量的情况下,一切都可能工作正常,因为变量不需要修改。

但是,在我的系统 (MS Visual Studio) 上,如果我“忘记”在 C++ 头文件中指定 extern "C" 链接规范,则 C 和 C++ 之间的链接不起作用。示例错误消息:

error LNK2001: unresolved external symbol "int global" (?_global)

同时,当我使用 dumpbin 实用程序检查包含 global 定义的已编译 C++ 源代码时,我看到了

00B 00000014 SECT4  notype       External     | ?global@@3HA (int global)

因此 MS Visual Studio 会破坏全局变量的名称,除非它们具有 C 链接 - 这使得 C 链接规范成为强制性的。


此外,请考虑以下示例:

namespace example {
int global;
}

如果全局变量在命名空间内,C 代码将无法访问它。在这种情况下,所有编译器都需要对 C++ 声明进行适当的链接规范:

namespace example {
extern "C" int global;
}

结论:

当您需要 C 链接时使用 extern "C" - 无论它是函数还是全局变量都无所谓。如果它是一个全局变量,它可能无论如何都有效,但不能保证(并且可能是危险的)。

关于c++ - extern 和 extern "C"用于变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38141390/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com