【问题标题】:What is the Effect of Declaring 'extern "C"' in the Header to a C++ Shared Library?在 C++ 共享库的标头中声明“外部“C””有什么影响?
【发布时间】:2010-04-06 19:20:41
【问题描述】:

基于this question,我了解将 C 库与 C++ 代码链接起来的构造目的。现在假设如下:

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

#ifdef __cplusplus
extern "C"
{
#endif

  // typedef struct ...;
  // function decls

#ifdef __cplusplus
}
#endif

... 效果如何?具体来说,我想知道该声明是否有任何不利的副作用,因为共享库被编译为 C++,而不是 C。

在这种情况下是否有任何理由使用 extern "C" 声明?

【问题讨论】:

  • 你的库是只能从 C++ 调用还是你也需要从 C 调用你的库?

标签: c++ c linux shared-libraries extern


【解决方案1】:

这很重要,因此编译器不会命名 mangle。 C++ 使用名称修饰来区分具有运算符重载的函数。

对二进制文件运行“/usr/bin/nm”以查看 C++ 对函数名称的作用: _ZSt8_DestroyIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEiEvT_S7_SaIT0_E

extern "C" 防止该名称被修改。

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

【讨论】:

  • 感谢您的信息。我是从客户端的角度考虑的,包括标题,而不是导出名称的库。
【解决方案2】:

在编译 C++ 时,方法名称会发生​​变化(重整) - 您将无法从另一个使用 C 的 dll/exe 调用该方法。

为了保留类和方法名称,您需要将它们编译为“C”而不进行名称修改。

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

【讨论】:

    【解决方案3】:

    #ifdef 保护 extern 声明是告诉 C 链接器符号具有 C(未损坏)符号表条目。 #ifdef 确保对 C 编译器编译的代码单元(文件)没有影响。

    【讨论】:

      【解决方案4】:

      extern "C" 用于 C++ API 的一个不利因素是它会阻止您出现函数重载:

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

      【讨论】:

      • 使用extern "C"的目的是让C和C++代码共享一个API,而C是最小的公分母,所以你必须遵守C编译器强制执行的规则。如果它一个 C++ API,那么你就不会使用 extern "C" 并且只使用 C++ 编译器进行编译,一切都会好起来的。
      • @quamrana - 他的问题是“对 C++ 共享库有什么影响”。这个问题不清楚他是否需要能够从 C 代码调用他的库。
      【解决方案5】:

      示例中的 #ifdef 意味着只有 C++ 编译器会看到 extern 包装了头文件,这意味着它将生成未损坏的名称。 C 编译器看不到 extern(它不会理解),但总是生成未损坏的名称。

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

      对于静态链接或与共享库的链接应该没有任何影响。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        相关资源
        最近更新 更多