我构建了一个名为 InterfaceLayer.so 的动态库。当我打电话时:
> nm InterfaceLayer
作为输出,我得到一些看起来像这样的符号:
00000e28 T _Z5startv
而我期待它是“开始”,就像我在代码中定义的函数的名称一样。
为什么会这样?
那是因为 C++ 名称修改
nm -C
使他们脱钩。
为防止名称篡改,
.
我的.h
extern "C"
{
void start();
void finish();
}
这将为它们提供“C”链接,这意味着它们不能被重载,不能通过引用传递,没有 c++ :)
听起来像C++ name mangling。
正如其他答案所提到的,这可能是因为 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++。