在头文件中声明'extern“C”到C ++共享库的效果是什么?

基于这个问题,我理解了链接C库和C ++代码的构造的目的。 现在假设如下:

我有一个用C ++编译器编译的'.so'共享库。 头文件有一个“typedef stuct”和一些函数声明。 如果标题包含extern“C”声明…

#ifdef __cplusplus extern "C" { #endif // typedef struct ...; // function decls #ifdef __cplusplus } #endif 

…有什么效果? 具体来说,我想知道是否有任何有害的副作用,因为共享库被编译为C ++,而不是C.

在这种情况下是否有任何理由有外部“C”声明?

Solutions Collecting From Web of "在头文件中声明'extern“C”到C ++共享库的效果是什么?"

这是非常重要的,这样编译器就不会命名为mangle。 C ++使用名称修改来区分与运算符重载的函数。

对二进制文件运行“/ usr / bin / nm”,看看C ++用你的函数名称做了什么:_ZSt8_DestroyIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiEvT_S7_SaIT0_E

extern“C”防止这个名字混乱。

IIRC,这使程序可以在运行时动态链接符号。 “插件”类型的体系结构很常见。

在编译C ++时,方法名称会发生​​变化(变形) – 而且您将无法从使用C的其他dll / exe中调用该方法

为了保持类和方法的名称,你需要将它们编译为“C”而不需要改名。

该库仍然是一个C ++库,但它的一些声明(extern“c”块)作为C方法公开。

#ifdef保护的extern声明是告诉C链接器这些符号具有C(unmangled)符号表项。 #ifdef确保在由C编译器编译的代码单元(文件)中不起作用。

使用extern "C"作为C ++ API的一个不利条件是它可以防止你的函数重载:

 extern "C" { // ILLEGAL - C linkage does not support function overloading void foo(int x); void foo(const char *str); } 

这个例子中的#ifdef意味着只有一个C ++编译器才会看到extern将头文件包装起来,这意味着它将产生非重名的名字。 AC编译器没有看到extern (它不会理解),但总是产生非mangled名称。

这意味着C和C ++编译器将在其目标文件中生成相同的符号,因此,无论哪个编译器都为声明的函数生成目标代码,所有目标文件都将成功链接,因为符号具有相同的链接和相同的名称。

静态链接或与共享库链接应该没有影响。