在MSVC中链接错误LNK2019,带有__imp__前缀的未解析符号,但应该来自静态lib

时间:2010-09-13 20:59:24

标签: visual-c++ cmake dllimport lnk2019 imp

我正在尝试将MSVC中的问题与我为g ++编写的项目联系起来。这是问题所在:

我将libssh构建为静态库作为我的应用程序的一部分,在cmake中添加目标

add_library(ssh_static STATIC $ libssh_SRCS)

Libssh在C中,所以我有'extern'C“{...}'将包含在我的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调用中被声明为静态库... < / p>

4 个答案:

答案 0 :(得分:28)

根据我记得的Windows日期,在MinGW构建的DLL中,__imp__符号前缀用于调用适当DLL的trampoline函数。然后,此符号由扩展名为.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执行此操作。

答案 1 :(得分:13)

不知道是不是你的情况,但是imp前缀可能意味着你正在编译Win32项目中的x64库。

答案 2 :(得分:1)

参加聚会的时间稍晚,但在将库与静态和动态链接混合到CRT时我遇到了同样的错误

答案 3 :(得分:0)

使用.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

CONSTANT现已弃用

我找到了另一种方法,在导出.lib的.DEF文件中使用:

 mainthreadid=_mainthreadid

并使用LIB.exe重新生成lib

在dll代码的导入头文件中......

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