c++ - extern和extern “C”用于变量

标签 c++ c linkage extern-c

我正在编写一个供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代码访问。如果省略此“语言链接”规范,则编译器将不做任何努力来进行适当的链接。对于功能而言,这会由于合并而导致链接失败。对于全局变量,一切都可能正常运行,因为变量不需要整形。

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

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

同时,当我使用global实用程序检查包含dumpbin定义的已编译C++源代码时,我看到了
00B 00000014 SECT4  notype       External     | ?global@@3HA (int global)

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

此外,请考虑以下示例:
namespace example {
    int global;
}

如果全局变量位于 namespace 内,则C代码将无法访问它。在这种情况下,所有编译器都需要在C++声明中使用正确的链接规范:
namespace example {
    extern "C" int global;
}

结论:

当需要C链接时,请使用extern "C"-不管是函数还是全局变量。如果它是全局变量,则无论如何它都可以工作,但是不能保证(并且可能很危险)。

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

相关文章:

c++ - 在函数中使用文件中的字符串

c++ - 是否可以从函数模板返回可变参数 lambda?

objective-c - 如果语句出错-xcode

c - 输入验证(具有多个值)

c - block 作用域和内部链接?

c++ - 具有外部链接的编译器的不同行为

c++ - 文件输入输出。无法使用文件路径

c - 通过 netlink 从内核向用户空间单播数据时失败

c++ - 显式类模板实例化的链接

c++ - 这如何打印整个数组?