我正在尝试使一个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)
,如果函数名称未弄乱,链接程序将如何解析符号名称。
可以在here中找到有关C++名称修饰的信息。
关于c++ - dylib中缺少符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32960554/