我正在尝试将MSVC中的问题与我为g ++编写的项目联系起来。这是问题所在:
我将libssh构建为静态库作为我的应用程序的一部分,在cmake中添加目标
add_library(ssh_static STATIC $ libssh_SRCS)
Libssh在C中,所以我有'extern'C“{...}'将包含在我的c ++源代码中。然后我使用
将ssh_static目标链接到我的可执行文件sshconnectiontesttarget_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>
答案 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;
}