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

发布于 2024-09-19 17:51:34 字数 646 浏览 11 评论 0原文

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

在 cmake 中添加目标

我将 libssh 构建为静态库,作为我的应用程序的一部分,使用add_library(ssh_static STATIC $libssh_SRCS)

Libssh 是 C 语言,所以我有 'extern "C" {...}' 包装包含在我的 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 调用中被声明为静态库...

I'm running into linking problems in MSVC for a project that I wrote for g++. Here's the problem:

I build libssh as a static library as part of my application, adding the target in cmake with

add_library(ssh_static STATIC $libssh_SRCS)

Libssh is in C, so I have 'extern "C" {...}' wrapping the includes in my c++ sources. I then link the ssh_static target to my executable, sshconnectiontest, with

target_link_libraries(sshconnectiontest ... ssh_static ...)

This all works fine in linux with gcc, but now in MSVC I get

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

for every libssh function I use.

Any ideas whats going wrong? I've read somewhere that the imp prefix means that the linker is expecting to link a .dll, but this should not be the case since ssh_static is declared a static library in the add_library call...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

网名女生简单气质 2024-09-26 17:51:35

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

Somewhat late to the party, but I got the same error when mixing libraries with static and dynamic linkage to the CRT

海螺姑娘 2024-09-26 17:51:35

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

BUT CONSTANT 现已弃用,

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

 mainthreadid=_mainthreadid

使用LIB.exe重新生成lib ...

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

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

Using a .DEF File

If you choose to use __declspec(dllimport) along with a .DEF file, you should change the .DEF file to use DATA or CONSTANT to reduce the likelihood that incorrect coding will cause a problem:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

The following table shows why:

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

BUT CONSTANT is now deprecated

i found another way, in the .DEF file of exported .lib use :

 mainthreadid=_mainthreadid

and regenerate the lib with LIB.exe

in the import header file of the dll code...

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}
夏有森光若流苏 2024-09-26 17:51:34

从我对 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

您需要通过 #define 定义 LIBSSH_STATIC#include 行之前,或作为 /D 选项。由于您使用的是 CMake,因此您可能会通过 CMakeLists.txt 中的 add_definitions 来执行此操作。

From what I remember of my Windows days, in MinGW-built DLLs, the __imp__ symbol prefix is used for the trampoline function that calls into the DLL proper. This symbol is then provided by a small static library with the extension .dll.a.

When you include libssh headers, you need to set a #define to indicate that you're expecting to link statically. If you don't, the libssh functions in the header will be declared __declspec(dllimport) and so the __imp__ symbols will be expected at link time.

I had a look at the libssh source and found this at the top of 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

You need to define LIBSSH_STATIC, either through #define before the #include <libssh.h> line, or as a /D option. Since you're using CMake, you'll probably do this through add_definitions in CMakeLists.txt.

遗弃M 2024-09-26 17:51:34

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

Don't know if it is your case, but the imp prefix may mean that you are compiling a x64 library in a Win32 project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文