8

我构建了一个名为 InterfaceLayer.so 的动态库。当我打电话时:

> nm InterfaceLayer

作为输出,我得到一些看起来像这样的符号:

00000e28  T _Z5startv

而我期待它是“开始”,就像我在代码中定义的函数的名称一样。

为什么会这样?

4

3 回答 3

15

那是因为 C++ 名称修改

nm -C

使他们脱钩。

为防止名称篡改,

  • 使用 C 编译器(gcc,而不是 g++),将源文件命名为 .c(不是 .cpp)
  • 或声明外部“C”:

.

我的.h

  extern "C" 
  {
        void start();
        void finish();
  }

这将为它们提供“C”链接,这意味着它们不能被重载,不能通过引用传递,没有 c++ :)

于 2011-05-17T19:30:39.130 回答
3

听起来像C++ name mangling

于 2011-05-17T19:31:14.480 回答
2

正如其他答案所提到的,这可能是因为 C++ 名称修改。如果您希望符号可以通过它的“未损坏”名称访问,并且它是在 C++ 中实现的,那么您需要extern "C"告诉 C++ 编译器它具有 C 链接。

在具有函数原型的标头中,您需要以下内容:

#if defined(__cplusplus)
extern "C" {
#endif

// the prototype for start()...


#if defined(__cplusplus)
}
#endif

这将确保如果该函数被 C++ 编译器使用,它将获得extern "C"声明,并且如果它被 C 模块使用,它不会被extern "C"说明符混淆。

如果在函数定义之前包含标头,则 .cpp 文件中的实现不需要这些东西。它将使用从先前声明中看到的链接规范。但是,我更喜欢仍然装饰函数定义,extern "C"以确保一切都同步(请注意,在 .cpp 文件中您不需要#ifdef预处理的东西 - 它总是被编译为 C++。

于 2011-05-17T19:34:27.490 回答