Search code examples
c++cgocgo

Missing symbols from a dylib


I'm trying to make a C api around a C++ library, so that I can later wrap it in Golang. I started by simply generating a dylib with one function so that I have a reference to look at. Then I made a wrapper around the actual library I wanted to use. When I generated all the symbols from the simple dylib i got this:

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

and I only declared a single function named Hello, so far so good

When I did what i thought was equivalent for the actual library, the go wrapper wouldn't compile and the symbols generated where

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

The symbol I was expecting was _SteamCAPI_Init (with the underscore because apparently Hello generated _Hello but instead i get something weirdish.

Is my compilation wrong, or is that the normal symbol that should be generated ?

The source files are available here (theres only like 30 important lines):
https://github.com/luxengine/steam
https://github.com/luxengine/steamc

EDIT (for future readers):

my problem at the time of writing was that my header file declaration had the extern "C" { but my source file did not, so gcc would mangle the names anyway and cgo wouldn't find it.

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

Solution

  • Firstly, dyld_stub_binder is the default generated symbol when you compile C++. You don't need to care about it.

    Secondly, __Z14SteamCAPI_Initv is actually the right symbol. Since C++ supports overloading, C++ functions are compiled with mangled symbol names, so that the functions name won't clash with each other. For example, you got two functions void do_something(int a) and void do_something(int a, int b), if the function names are not mangled, how would the linker resolve symbol names.

    Info about C++ name mangling can be found here.