我正在编写一个供C程序使用的C++共享库。但是,我有一个关于extern
和extern "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/