Имя компилятора C++ VS2013 Mangling, определенное с помощью extern C

Я пытаюсь создать консольное приложение WIN32, которое использует текущую статическую библиотеку 2.12.28 ftd2xx.lib от FTDI. Я использую VS2013 и собственный неуправляемый C++. Мой звонок выглядит так.

#include "../ftd2xx.h"
 . . .
    DWORD port_count = 0;
    FT_STATUS status = FT_OK;
    status = FT_CreateDeviceInfoList(&port_count);

Когда я компилирую, я получаю ошибку ссылки

GetTopazVCP.obj : error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList@4 referenced in function "unsigned long __cdecl Get1stVirtualComPort(unsigned long *)" (?Get1stVirtualComPort@@YAKPAK@Z)

Неразрешенный символ __imp__FT_CreateDeviceInfoList@4 выглядит как искаженная версия имени функции FT_CreateDeviceInfoList. Так что это не решается в ftd2xx.lib, который использует имена C. Чего я не понимаю, так это почему компилятор исказил имя, когда файл ftd2xx.h имеет условный внешний вид "C"

#ifdef __cplusplus
   extern "C" {
#endif
. . .
FTD2XX_API
    FT_STATUS WINAPI FT_CreateDeviceInfoList(
    LPDWORD lpdwNumDevs
    );
...
#ifdef __cplusplus
}
#endif

обертывание всех FT_??? декларации. Я подтвердил, что __cplusplus определяется во время компиляции. Любые идеи, что вызывает неожиданное искажение имени?


person JonN    schedule 03.11.2017    source источник
comment
Это ошибка связывания. Вы уверены, что добавили библиотеку ftd2xx.lib в свой проект?   -  person miradham    schedule 03.11.2017
comment
Префикс imp означает, что код функции импортирован из библиотеки DLL (а не из статической библиотеки), а @n — это просто часть имени функции (поскольку в ней используется соглашение о вызовах Microsoft __stdcall вместо обычное соглашение о вызовах C (__cdecl); это то, что означает макрос WINAPI в объявлении функции). Другими словами, здесь не происходит искажения имени C++, и у вас просто обычная ошибка компоновщика, предположительно потому, что вам не хватает библиотеки в настройках компоновщика вашего проекта.   -  person    schedule 03.11.2017
comment
@ChronoKitsune Я приходил к выводу, что это не было искажением имени после того, как я переключил исходный файл вызова с C ++ на стандартный C и получил ту же ошибку. Я связывал статическую библиотеку, но, видимо, файл заголовка, который я использовал, был для версии DLL. Я заменил файл ftd2xx.lib версией DLL, и он успешно скомпилировался. Глядя на ftd2xx.h, если вы хотите использовать статическую библиотеку, вам нужно #define FTD2XX_STATIC перед #include ftd2xx.h   -  person JonN    schedule 03.11.2017
comment
Примечание. Суффикс @... указывает количество байтов, используемых в стеке для входных параметров, в данном случае @4 для 4-байтового или 32-битного параметра.   -  person rcgldr    schedule 03.11.2017
comment
Не называется искажением, экспортированные функции C декорированы. Это украшение stdcall, постфикс @4 указывает на размер передаваемых аргументов в байтах. Это помогает компоновщику обнаруживать несоответствия соглашения о вызовах, что происходит только в 32-битном коде. Префикс imp говорит вам, что это вовсе не функция, а переменная. Он указывает на функцию во время выполнения, помогает загрузчику ОС генерировать немного более быстрый код, когда он связывает функцию. В противном случае это обычная старая ошибка компоновщика, неизменно возникающая из-за того, что забывают связать правильную библиотеку, иногда из-за ошибки объявления.   -  person Hans Passant    schedule 03.11.2017


Ответы (1)


Как отметил ChronoKitsune в своем комментарии, здесь нет искажения имени. Проблема заключалась в том, что я связывал статическую версию библиотеки FTDI, но по умолчанию для заголовочного файла ftd2xx.h объявляется FT_??? функции как вызовы версии DLL. Когда я заменил статическую версию ftd2xx.lib версией DLL ftd2xx.lib, она была успешно собрана. FTDI предоставляет только одну версию заголовка ftd2xx.h, и, внимательно изучив его, я обнаружил, что если вы хотите использовать статический ftd2xx.lib, вам нужно #define FTD2XX_STATIC перед включением ftd2xx.h.

#define FTD2XX_STATIC
#include "ftd2xx.h"
person JonN    schedule 03.11.2017