Lier LNK2019 d'erreur dans MSVC, symboles non résolus avec __imp__ préfixe, mais devrait être de lib statique

StackOverflow https://stackoverflow.com/questions/3704374

Question

Je suis en cours d'exécution en reliant des problèmes à MSVC pour un projet que j'ai écrit pour g ++. Voici le problème:

Je construis libssh comme une bibliothèque statique dans le cadre de ma demande, en ajoutant la cible dans CMake avec

add_library (ssh_static STATIC $ libssh_SRCS)

libssh est en C, donc je 'extern "C" {...}' enveloppant le comprend dans mes c ++ sources. Je vous redirigent ensuite la cible ssh_static à mon exécutable, sshconnectiontest, avec

TARGET_LINK_LIBRARIES (sshconnectiontest ... ssh_static ...)

Tout cela fonctionne très bien sous Linux avec gcc, mais maintenant je reçois MSVC

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

pour toutes les fonctions libssh-je utiliser.

Toutes les idées ce qui se passe mal? Je l'ai lu quelque part que le diablotin des moyens préfixe l'éditeur de liens ATTEND pour lier un .dll, mais cela ne devrait pas être le cas puisque ssh_static est déclaré une bibliothèque statique dans l'appel add_library ...

Était-ce utile?

La solution

D'après ce que je me souviens de mes jours de Windows, dans les DLL construites MinGW, le préfixe symbole __imp__ est utilisé pour la fonction de trampoline que les appels dans la DLL appropriée. Ce symbole est alors fourni par une petite bibliothèque statique avec l'extension .dll.a.

Lorsque vous incluez les en-têtes libssh, vous devez définir un #define pour indiquer que vous vous attendez à un lien statique. Si vous ne le faites pas, les fonctions de libssh dans l'en-tête seront déclarés __declspec(dllimport) et donc les symboles __imp__ seront attendus au moment de la liaison.

J'ai eu un coup d'oeil à la source de libssh et trouvé ce en haut 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

Vous devez définir LIBSSH_STATIC, soit par #define avant la ligne de #include <libssh.h>, ou en option /D. Puisque vous utilisez CMake, vous allez probablement faire cela par add_definitions dans CMakeLists.txt.

Autres conseils

Je ne sais pas si elle est votre cas, mais le préfixe diablotin peut signifier que vous compilez une bibliothèque x64 dans un projet Win32.

Un peu tard pour le parti, mais je suis la même erreur lors du mélange des bibliothèques avec une liaison statique et dynamique du CRT

L'utilisation d'un fichier .def

Si vous choisissez d'utiliser __declspec (dllimport) avec un fichier .def, vous devez modifier le fichier .def d'utiliser les données ou CONSTANT pour réduire la probabilité que le codage incorrect provoquera un problème:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

Le tableau ci-dessous pourquoi:

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

et CONSTANT est maintenant désapprouvée

je l'ai trouvé une autre façon, dans le fichier .def d'utilisation .lib exporté:

 mainthreadid=_mainthreadid

et régénérer le répertoire lib avec lib.exe

dans le fichier d'en-tête d'importation du code dll ...

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top