Я пытаюсь скомпилировать какой-либо сторонний код C ++ в свое 32-битное приложение C ++ с Visual Studio 2017 (обновление с Visual Studio 6.0). У меня есть .h файлы и .lib файл от третьего лица. Компоновщик находит библиотеку, но не находит декорированные имена, содержащиеся внутри. Это происходит потому, что компилятор заменяет «__int8» на «char».
Ошибка компоновщика:
LNK2019 unresolved external symbol "signed char __cdecl Check_The_Thing(void)" (?Check_The_Thing@@YACXZ) referenced in function (redacted)
Функция определена в .h:
_declspec(dllexport) API_RETURN_TYPE Check_The_Thing ( void );
API_RETURN_TYPE определен в .h:
_declspec(dllimport) typedef signed __int8 int_8;
_declspec(dllimport) typedef int_8 API_RETURN_TYPE;
Используя dumpbin / exports, я вижу, что моя lib и связанные с ней dll экспортируют Check_The_Thing:
?Check_The_Thing@@YA_DXZ (__int8 __cdecl Check_The_Thing(void))
Используя undname, я вижу, что декорированное имя в lib правильно вычисляется:
Undecoration of :- "?Check_The_Thing@@YA_DXZ"is :- "__int8 __cdecl Check_The_Thing(void)"
Но созданное компилятором оформленное имя НЕ оценивается должным образом (на основе кода):
Undecoration of :- "?Check_The_Thing@@YACXZ"is :- "signed char __cdecl Check_The_Thing(void)"
В соответствии с https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling, «C» в YACXZ оценивается как «подписанный символ», а «_D» — «__int8». Я не могу понять, почему компилятор интерпретирует API_RETURN_TYPE как «char» вместо «__int8». Понятно, что lib / dll экспортирует должен иметь «_C» вместо «_D», учитывая, что API_RETURN_TYPE является «подписанным __int8», а не просто «__int8».
Я возился с кучей настроек компилятора без удачи. Как предложено здесь (Не удается найти оформленное имя функции в dll), Я убедился, что я использую MBCS вместо Unicode (раньше это не было установлено), но это также не имело никакого значения.
Конкретное определение API_RETURN_TYPE как __int8 не имеет никакого значения, кроме как заменить «C» на «D» (прогресс!), А также в случае, когда undname отображает тип возвращаемого значения как «char» вместо «Знаковый char». Изменение типа возвращаемого определения функции на __int8 имеет тот же эффект, что и изменение API_RETURN_TYPE.
Итак, мой вопрос: как я могу заставить компилятор правильно определить мой экспорт с помощью «__int8» (или «_D») вместо char («D»)?
Примечание: ошибка компоновщика одинакова для случаев, когда используются __int16, __int32 и __int64.
РЕДАКТИРОВАТЬ: На самом деле, библиотека определяет типы __int64, но я не использую. Нет никаких ошибок компоновщика __int64.
По крайней мере, начиная с Visual Studio 2003 (!), «Тип данных __int8 является синонимом типа char».
Очевидно, что компилятор не может иметь разные названия для двух способов назвать один и тот же тип.
Также проницательным является эта страница что показывает, что __int8
является (подписано) char
но __int64
является не long long
; последние просто эквивалентны.
Других решений пока нет …