我正在尝试使一个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/

10-17 00:32