MSVC 中的链接错误 LNK2019,带有 __imp__ 前缀的未解析符号,但应该来自静态库
Posted
技术标签:
【中文标题】MSVC 中的链接错误 LNK2019,带有 __imp__ 前缀的未解析符号,但应该来自静态库【英文标题】:Linking error LNK2019 in MSVC, unresolved symbols with __imp__ prefix, but should be from static lib 【发布时间】:2011-04-11 21:18:35 【问题描述】:对于我为 g++ 编写的项目,我在 MSVC 中遇到了链接问题。问题来了:
我将 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 调用中被声明为静态库...
【问题讨论】:
【参考方案1】:根据我对 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
您需要在#include <libssh.h>
行之前通过#define
定义LIBSSH_STATIC
,或者作为/D
选项定义。由于您使用的是 CMake,因此您可能会通过 add_definitions
in CMakeLists.txt
执行此操作。
【讨论】:
做到了 :-) 我在编译 libssh 时设置了标志,但没有为其他项目设置标志。谢谢! 黄金答案!帮了我很多忙。【参考方案2】:不知道是不是你的情况,但是imp前缀可能意味着你正在Win32项目中编译x64库。
【讨论】:
这实际上是我在 Windows 上的问题。我无意中将 64 位 dll 与 32 位 dll 链接。 如果你选择了“在静态库中使用 MFC”选项是错误的,你会得到错误。【参考方案3】:聚会有点晚了,但在将库与 CRT 的静态和动态链接混合时遇到了同样的错误
【讨论】:
【参考方案4】:使用 .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;
【讨论】:
以上是关于MSVC 中的链接错误 LNK2019,带有 __imp__ 前缀的未解析符号,但应该来自静态库的主要内容,如果未能解决你的问题,请参考以下文章
了解 Visual Studio 2010 中的此错误 (LNK 2019)
Error:LNK2019无法解析的外部符号_sscanf, _vsprintf