27

对于我为 g++ 编写的项目,我在 MSVC 中遇到了链接问题。这是问题所在:

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

add_library(ssh_static 静态 $libssh_SRCS)

Libssh 在 C 中,所以我在我的 c++ 源代码中包含了 'extern "C" {...}'。然后我将 ssh_static 目标链接到我的可执行文件 sshconnectiontest,使用

target_link_libraries(sshconnectiontest ... ssh_static ...)

这一切都可以在带有 gcc 的 linux 中正常工作,但现在在 MSVC 中我得到了

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

对于我使用的每个 libssh 函数。

任何想法出了什么问题?我在某处读到imp前缀意味着链接器期望链接一个 .dll,但这不应该是这种情况,因为 ssh_static 在 add_library 调用中被声明为静态库......

4

4 回答 4

32

根据我对 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_definitionsCMakeLists.txt.

于 2010-09-15T01:43:30.190 回答
12

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

于 2011-05-05T08:35:34.210 回答
1

聚会有点晚了,但是在将具有静态和动态链接的库与 CRT 混合时,我遇到了同样的错误

于 2017-05-10T05:48:35.097 回答
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 重新生成库

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

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}
于 2011-08-05T21:31:25.970 回答