dylib 中缺少符号
Missing symbols from a dylib
我正在尝试围绕 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
编辑(对于未来的读者):
我在撰写本文时的问题是我的头文件声明有 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++ 库创建一个 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
编辑(对于未来的读者):
我在撰写本文时的问题是我的头文件声明有 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。