Error de enlace LNK2019 en MSVC, símbolos sin resolver con prefijo imp, pero debe ser de lib estática


Me estoy topando con problemas de enlace en MSVC para un proyecto que escribí para g++. Este es el problema:

Compilo libssh como una biblioteca estática como parte de mi aplicación, agregando el destino en cmake con

Add_library (ssh_static STATIC lib libssh_SRCS)

Libssh está en C, así que tengo 'extern" C" {...} 'empaquetando las inclusiones en mis fuentes de c++. Luego enlazo el destino ssh_static a mi ejecutable, sshconnectiontest, con

Target_link_libraries(sshconnectiontest ... ssh_static ...)

Todo esto funciona bien en linux con gcc, pero ahora en MSVC obtengo

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

Para cada función libssh que uso.

¿Alguna idea de lo que va mal? He leído en alguna parte que el prefijo imp significa que el enlazador espera enlazar a .dll, pero este no debería ser el caso ya que ssh_static se declara una biblioteca estática en la llamada add_library...

Author: Jack Kelly, 2010-09-14

4 answers

De lo que recuerdo de mis días en Windows, en las DLL construidas por MinGW, el prefijo de símbolo __imp__ se usa para la función trampolín que llama a la DLL propiamente dicha. Este símbolo es proporcionado por una pequeña biblioteca estática con la extensión .dll.a.

Cuando incluyes encabezados libssh, necesitas establecer un #define para indicar que estás esperando enlazar estáticamente. Si no lo hace, las funciones libssh en el encabezado se declararán __declspec(dllimport) y por lo tanto los símbolos __imp__ se esperarán en el enlace tiempo.

Eché un vistazo a la fuente libssh y encontré esto en la parte superior de 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

Necesita definir LIBSSH_STATIC, ya sea a través de #define antes de la línea #include <libssh.h>, o como una opción /D. Ya que estás usando CMake, probablemente lo harás a través de add_definitions en CMakeLists.txt.

 28
Author: Jack Kelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-15 01:43:30

No sé si es tu caso, pero el prefijo imp puede significar que estás compilando una biblioteca x64 en un proyecto Win32.

 12
Author: Ago,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-05 08:35:34

Usando a .DEF File

Si elige usar _ _ declspec (dllimport) junto con a.DEF archivo, usted debe cambiar el .DEF archivo para utilizar DATOS o CONSTANTE para reducir la probabilidad de que la codificación incorrecta causará un problema:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

La siguiente tabla muestra por qué:

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

PERO La CONSTANTE ahora está en desuso

Encontré otra manera, en el.Archivo DEF de exportado .lib uso :

 mainthreadid=_mainthreadid

Y regenerar la lib con LIB.exe

En el archivo de cabecera de importación del código dll...

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}
 0
Author: Tanguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-05 22:41:47

Algo tarde para el partido, pero tengo el mismo error al mezclar bibliotecas con enlace estático y dinámico a la CRT

 0
Author: kreuzerkrieg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-10 05:48:35