web-dev-qa-db-de.com

Verbindungsfehler LNK2019 in MSVC, nicht aufgelöste Symbole mit dem Präfix __imp__, sollten jedoch aus der statischen Bibliothek stammen

Ich habe Probleme mit der Verknüpfung von Problemen in MSVC für ein Projekt, das ich für g ++ geschrieben habe. Hier ist das Problem:

Ich baue libssh als statische Bibliothek als Teil meiner Anwendung und füge das Ziel in cmake mit hinzu

add_library (ssh_static STATIC $ libssh_SRCS)

Libssh ist in C, ich habe also "extern" C "{...}", das die Include-Dateien in meine C++ - Quellen einschließt. Dann verknüpfe ich das ssh_static-Ziel mit meiner ausführbaren Datei, sshconnectiontest, mit 

target_link_libraries (sshconnectiontest ... ssh_static ...)

Das alles funktioniert gut in Linux mit gcc, aber jetzt in MSVC bekomme ich 

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

für jede libssh-Funktion, die ich verwende.

Irgendwelche Ideen, was schief läuft? Ich habe irgendwo gelesen, dass das Präfix imp bedeutet, dass der Linker erwartet, eine .dll zu verknüpfen. Dies sollte jedoch nicht der Fall sein, da ssh_static im Aufruf von add_library als statische Bibliothek deklariert wird.

25
dlonie

Soweit ich mich an meine Windows-Tage erinnere, wird in MinGW-DLLs das __imp__-Symbolpräfix für die Trampolin-Funktion verwendet, die die eigentliche DLL aufruft. Dieses Symbol wird dann von einer kleinen statischen Bibliothek mit der Erweiterung .dll.a bereitgestellt.

Wenn Sie libssh-Header einschließen, müssen Sie einen #define setzen, um anzugeben, dass Sie eine statische Verknüpfung erwarten. Wenn Sie dies nicht tun, werden die libssh-Funktionen im Header als __declspec(dllimport) deklariert, sodass die __imp__-Symbole zum Zeitpunkt der Verknüpfung erwartet werden.

Ich habe mir die libssh-Quelle angesehen und das oben in libssh.h gefunden:

#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

Sie müssen LIBSSH_STATIC entweder durch #define vor der #include <libssh.h>-Zeile oder als /D-Option definieren. Da Sie CMake verwenden, tun Sie dies wahrscheinlich über add_definitions in CMakeLists.txt.

28
Jack Kelly

Ich weiß nicht, ob es Ihr Fall ist, aber das imp-Präfix kann bedeuten, dass Sie eine x64-Bibliothek in einem Win32-Projekt kompilieren.

13
Ago

Etwas spät für die Party, aber ich habe den gleichen Fehler beim Mischen von Bibliotheken mit statischer und dynamischer Verbindung zum CRT erhalten

1
kreuzerkrieg

Verwenden einer DEF-Datei

Wenn Sie __declspec (dllimport) zusammen mit einer DEF-Datei verwenden, sollten Sie die DEF-Datei in DATA oder CONSTANT ändern, um die Wahrscheinlichkeit zu verringern, dass eine falsche Codierung zu einem Problem führt:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

Die folgende Tabelle zeigt, warum:

Keyword      Emits in the import library   Exports
CONSTANT     _imp_ulDataInDll              _ulDataInDll
             _ulDataInDll                  

DATA         _imp_ulDataInDll              _ulDataInDll

http://msdn.Microsoft.com/de-de/library/aa271769(v=vs.60).aspx

, ABER CONSTANT ist jetzt veraltet

ich habe einen anderen Weg gefunden, in der .DEF-Datei der exportierten .lib Verwendung zu finden:

 mainthreadid=_mainthreadid

und regenerieren Sie die lib mit LIB.exe

in der Import-Header-Datei des DLL-Codes ...

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