缺少来自dylib的符号

时间:2015-10-06 01:58:53

标签: 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

EDIT(面向未来的读者):

我在编写本文时遇到的问题是我的头文件声明有extern "C" {但我的源文件没有,所以gcc会破坏名称,而cgo也找不到它。

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

1 个答案:

答案 0 :(得分:1)

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

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

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