2015-10-06 3 views
1

Я пытаюсь создать C api в библиотеке C++, чтобы позже ее можно было обернуть в Golang. Я начал с простого создания dylib с одной функцией, так что у меня есть ссылка для просмотра. Затем я сделал обертку вокруг фактической библиотеки, которую я хотел использовать. Когда я сгенерировал все символы из простого dylib я получил это:Отсутствующие символы из dylib

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

и я только объявил одну функцию с именем Hello, до сих пор так хорошо

Когда я сделал то, что я думал, что было равнозначно за действительное библиотеки, идти обертка не будет компилировать и символы, там где

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, но вместо этого я получаю что-то странное.

Является ли моя компиляция неправильной или является нормальным символом, который должен быть сгенерирован?

Исходные файлы доступны здесь (Theres только как 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

Во-первых, dyld_stub_binder является порожденным по умолчанию символом при компиляции C++. Вам не нужно заботиться об этом.

Во-вторых, __Z14SteamCAPI_Initv на самом деле является правильным символом. Поскольку C++ поддерживает перегрузку, функции C++ скомпилированы с искаженными именами символов, так что имя функции не будет конфликтовать друг с другом. Например, у вас есть две функции void do_something(int a) и void do_something(int a, int b), если имена функций не искажены, как бы компоновщик разрешил имена символов.

Информация о когниции имени C++ может быть найдена here.

+0

Хм, нормально, даже если я экспортирую C "... bool SteamCAPI_Init ...}'? Потому что это то, что я делаю, полагал, что это не приведет к искажению имен. Если да, то любой способ не калечить их, поэтому компилятор go может восстановить имя только с помощью 'SteamCAPI_Init'? – user2475269

+0

Экспорт «C» предназначен для того, чтобы C знал, что функция C++, это не влияет на компиляцию. – Krypton

+0

, если вы хотите, чтобы символ был 'SteamCAPI_Init', вам нужно создать C-оболочку для' __Z14SteamCAPI_Initv'. – Krypton