Подтвердить что ты не робот

Ошибка связи LNK2019 в MSVC, неразрешенные символы с префиксом __imp__, но должны быть из статического lib

Я запускаю ссылки на проблемы в MSVC для проекта, который я написал для g++. Здесь проблема:

Я создаю libssh как статическую библиотеку как часть моего приложения, добавляя цель в cmake с помощью

add_library (ssh_static STATIC $libssh_SRCS)

Libssh находится в C, поэтому у меня есть "extern" C "{...}", который завершает включения в мои источники С++. Затем я связываю цель ssh_static с моим исполняемым файлом sshconnectiontest с

target_link_libraries (sshconnectiontest... ssh_static...)

Все работает отлично в linux с gcc, но теперь в MSVC я получаю

error LNK2019: unresolved external symbol __imp__[function names here] referenced in [filename]

для каждой используемой функции libssh.

Любые идеи, что происходит не так? Я где-то читал, что префикс imp означает, что компоновщик ожидает ссылку на .dll, но это не должно быть так, поскольку ssh_static объявляется статической библиотекой в ​​вызове add_library...

4b9b3361

Ответ 1

Из того, что я помню из моих дней Windows, в DLL, созданных в MinGW, префикс символа __imp__ используется для функции батута, которая вызывает в собственно DLL. Этот символ затем предоставляется небольшой статической библиотекой с расширением .dll.a.

Когда вы включаете заголовки libssh, вам нужно установить #define, чтобы указать, что вы ожидаете связывать статически. Если вы этого не сделаете, функции libssh в заголовке будут объявлены __declspec(dllimport), поэтому символы __imp__ будут ожидаться во время соединения.

Я посмотрел источник libssh и нашел это в верхней части libssh.h:

#ifdef LIBSSH_STATIC
  #define LIBSSH_API
#else
  #if defined _WIN32 || defined __CYGWIN__
    #ifdef LIBSSH_EXPORTS
      #ifdef __GNUC__
        #define LIBSSH_API __attribute__((dllexport))
      #else
        #define LIBSSH_API __declspec(dllexport)
      #endif
    #else
      #ifdef __GNUC__
        #define LIBSSH_API __attribute__((dllimport))
      #else
        #define LIBSSH_API __declspec(dllimport)
      #endif
    #endif
  #else
    #if __GNUC__ >= 4
      #define LIBSSH_API __attribute__((visibility("default")))
    #else
      #define LIBSSH_API
    #endif
  #endif
#endif

Вам нужно определить LIBSSH_STATIC, либо через #define до строки #include <libssh.h>, либо как параметр /D. Поскольку вы используете CMake, вы, вероятно, сделаете это через add_definitions в CMakeLists.txt.

Ответ 2

Не знаю, является ли это ваш случай, но префикс imp может означать, что вы компилируете библиотеку x64 в проекте Win32.

Ответ 3

Использование файла .DEF

Если вы решите использовать __declspec (dllimport) вместе с файлом .DEF, вы должны изменить файл .DEF для использования DATA или CONSTANT, чтобы уменьшить вероятность неправильного кодирования проблемы:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

В следующей таблице показано, почему:

Keyword      Emits in the import library   Exports
CONSTANT     _imp_ulDataInDll              _ulDataInDll
             _ulDataInDll                  

DATA         _imp_ulDataInDll              _ulDataInDll

http://msdn.microsoft.com/en-us/library/aa271769(v=vs.60).aspx

НО ПОСТОЯНКА теперь устарела

Я нашел другой способ, в .DEF файле экспортируемого .lib:

 mainthreadid=_mainthreadid

и восстановить lib с помощью LIB.exe

в файле заголовка импорта кода dll...

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}

Ответ 4

Несколько поздно для вечеринки, но я получил ту же ошибку при смешивании библиотек со статической и динамической связью с CRT