c++ - dylib 中缺少符号

标签 c++ c go cgo

我正在尝试围绕 C++ 库制作一个 C api,以便稍后可以将其包装在 Golang 中。我首先简单地生成一个带有一个函数的 dylib,这样我就有一个引用可以看。然后我围绕我想使用的实际库做了一个包装。当我从简单的 dylib 生成所有符号时,我得到了这个:

MacbookMainframe:c hydroflame$ nm -a clib/libxyz.dylib 
0000000000000f90 T _Hello
                 U dyld_stub_binder

而且我只声明了一个名为 Hello 的函数,到目前为止还不错

当我做了我认为对实际库等效的操作时,go 包装器无法编译并且符号生成位置

MacbookMainframe:c hydroflame$ nm -a ../luxengine.net/steamc/libsteam.dylib 
                 U _SteamAPI_Init
0000000000000f60 T __Z14SteamCAPI_Initv
                 U dyld_stub_binder

我期待的符号是 _SteamCAPI_Init(带有下划线,因为显然 Hello 生成了 _Hello 但我得到了一些奇怪的东西。

是我的编译有误,还是应该生成正常的符号?

源文件在这里可用(只有大约 30 行重要的行):
https://github.com/luxengine/steam
https://github.com/luxengine/steamc

编辑(对于 future 的读者):

我在撰写本文时遇到的问题是我的头文件声明有 extern "C"{ 但我的源文件没有,所以 gcc 无论如何都会破坏名称,而 cgo 找不到

MacbookMainframe:steamc hydroflame$ nm -a libsteam.dylib 
                 U _SteamAPI_Init
0000000000000f60 T _SteamCAPI_Init
                 U dyld_stub_binder

最佳答案

首先,dyld_stub_binder是编译C++时默认生成的符号。你不需要关心它。

其次,__Z14SteamCAPI_Initv 实际上是正确的符号。由于 C++ 支持重载,因此 C++ 函数使用错位符号名称进行编译,因此函数名称不会相互冲突。例如,您有两个函数 void do_something(int a)void do_something(int a, int b),如果函数名称没有被破坏,链接器将如何解析符号名称。

可以找到有关 C++ 名称修改的信息 here .

关于c++ - dylib 中缺少符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32960554/

相关文章:

c++ - 找不到 Xcode build设置 - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS

c++ - 如何检索 Windows XP 中的所有事件日志?

c - 如何在不推送新堆栈帧的情况下溢出堆栈?

c - 二维数组是否需要事先知道它在 C 中的大小?

mongodb - 无法安装最新版本的mongo-go-driver(v1.2.1)

Go:如何从 slice 中删除元素并在内存中修改它

c++ - 关于转换构造函数和赋值运算符

c# - 我可以将 double 的浮点部分转换为整数(不使用字符串转换)吗?

c++ - 一个非常弱的引用(不能变成共享)

json - 如何在 GO 中访问 JSON 的字段