宣布';“外部”;"';在标题中添加到C++;共享库? 基于理解C++库与C++代码的连接的构造目的。现在假设如下: 我有一个用C++编译器编译的'.SO '共享库。标头有一个“typedef stuct”和许多函数声明。如果标头包含外部“C”声明 #ifdef __cplusplus extern "C" { #endif // typedef struct ...; // function decls #ifdef __cplusplus } #endif

宣布';“外部”;"';在标题中添加到C++;共享库? 基于理解C++库与C++代码的连接的构造目的。现在假设如下: 我有一个用C++编译器编译的'.SO '共享库。标头有一个“typedef stuct”和许多函数声明。如果标头包含外部“C”声明 #ifdef __cplusplus extern "C" { #endif // typedef struct ...; // function decls #ifdef __cplusplus } #endif,c++,c,linux,shared-libraries,extern,C++,C,Linux,Shared Libraries,Extern,。。。效果如何?具体来说,我想知道是否有任何有害的声明的副作用,因为共享库被编译为C++,而不是C.< P>是否有理由在这种情况下有“C”声明?在编译C++方法名称更改(Mangle)时,< P> >不能从另一个使用C.的DLL/EXE调用该方法 为了保持类和方法的名称,您需要将它们编译为“C”,而不会损坏名称 库仍然是C++库,但是它的一些声明(外部的C)块中的C方法是这样的。 < P> > IFDEF < /Cube >代码> ExtNe>代码>声明是告诉C链接器符号有C(unMulin

。。。效果如何?具体来说,我想知道是否有任何有害的声明的副作用,因为共享库被编译为C++,而不是C.<
<> P>是否有理由在这种情况下有“C”声明?在编译C++方法名称更改(Mangle)时,

< P> >不能从另一个使用C.</P>的DLL/EXE调用该方法 为了保持类和方法的名称,您需要将它们编译为“C”,而不会损坏名称


库仍然是C++库,但是它的一些声明(外部的C)块中的C方法是这样的。

< P> <代码> > IFDEF < /Cube >代码> ExtNe>代码>声明是告诉C链接器符号有C(unMulink)符号表项。
#ifdef
确保由C编译器编译的代码单元(文件)中没有任何影响。

这一点很重要,这样编译器就不会命名mangle。C++使用名称的模糊来区分函数与操作符重载。

运行“/Ur/bin /nm”,以二进制方式查看C++对函数名的作用: _ZSt8销毁9 gnu cxx17正常迭代器6矢量化

外部代码“C”防止名称被破坏


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

对C++ API使用<代码>外部“C”<代码>的一个不利之处是它防止了函数重载:

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

>代码> > IFIFF < /C> >意味着只有一个C++编译器会看到 ExtNe//Cuth>包装头文件,这意味着它将产生未被修改的名称。C编译器看不到

外部代码(它无法理解),但总是生成无损坏的名称

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


静态链接或与共享库链接都不会产生任何影响。

谢谢您提供的信息。我从客户端的角度来考虑它,包括头,而不是导出名称的库。使用代码>外部“C”<代码>的点是C和C++代码共享一个API,C是最低的公分母,所以你必须遵守C编译器强制执行的规则。如果是C++ API,那么你就不会使用<代码>外部> C“< /C>”,只使用C++编译器编译,一切都会好的。@ Quangra-他的问题是“对C++共享库的影响是什么”。目前还不清楚他是否需要从C代码中调用他的库。你的库只需要从C++调用,还是需要从C调用你的库?