Я пытаюсь создать C api вокруг библиотеки C ++, чтобы потом обернуть его в 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
РЕДАКТИРОВАТЬ (для будущих читателей):
На момент написания этой статьи у меня возникла проблема: 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)
Если имена функций не искажены, как компоновщик будет разрешать имена символов.
Информацию об искажении имен в C ++ можно найти Вот.
Других решений пока нет …