如何在MSVC中使用MingW编译的库?

Num*_*our 14 c++ compatibility mingw static-libraries visual-c++

我用MingW/MSYS编译了几个库......生成的静态库总是.a文件.当我尝试将库与MSVC项目链接时,Visual Studio会抛出"未解析的外部符号"......这意味着.a静态库与MS C++链接器不兼容.我认为它必须转换为MSVC兼容的.lib文件.

.a和.lib只是.o或.obj文件的AR档案,所以有没有办法在MSVC项目中使用MingW编译的库?或者我是否必须在一个编译器/链接器中编译/链接所有内容 - 仅限MSVC/MingW?据说MingW编译器与MSVC兼容.

我读了一些关于这个主题的线索,但是他们大多说将文件重命名为.lib应该可以完成工作,但遗憾的是它对我不起作用.

我试图链接的库是用C语言编写的.

MSVC Linker抛出的错误如下:

error LNK2019: unresolved external symbol "int __cdecl openssl_call(struct ssl_State *,int,int,int)" (?openssl_call@@YAHPAUssl_State@@HHH@Z) referenced in function _main MyAPP.obj
Run Code Online (Sandbox Code Playgroud)

...还有4个相同的错误,指的是从我的app调用的其他函数.

谢谢你的建议.

shf*_*301 12

基于此错误,您将发表评论:

错误LNK2019:无法解析的外部符号 "INT __cdecl openssl_call(结构ssl_State*,INT,INT,INT)"(openssl_call @@ YAHPAUssl_State @@ HHH @ Z?)在函数_main MyAPP.obj引用的所有其他4次失误同样是与其他功能名称

尝试extern "C"为openssl添加包含文件.例如:

extern "C" {
include "openssl.h"
}
Run Code Online (Sandbox Code Playgroud)

使用extern"C"将指示编译器函数使用C链接,而不是C++,这将阻止它对函数执行名称修改.所以它会在库中寻找openssl_call函数,而不是?openssl_call @@ YAHPAUssl_State @@ HHH @.

  • 这当然是一个可能的解决方案,但如果确实如此,我很惊讶SSL本身并不这样做 - 也许作者讨厌C++ :-) (4认同)

小智 10

这些库是兼容的,但前提是您提供C接口.MSVC和g ++使用不同的名称修改方案,因此您无法轻松地将创建的C++代码与另一个创建的代码链接起来.

  • 那么我应该怎么做才能将 MingW 编译的 lib 与 MSVC 编译的可执行文件成功链接呢? (2认同)

coa*_*nor 9

我介绍了在MSVC中使用mingw编译的dll的相同情况.我使用以下工具使其工作:
1)使用gcc:

gcc -shared -o your_dll.dll your_dll_src.c -Wl , - output-def,your_dll.def

粗体指定gcc将生成一个脚本导出项目的*def文件.然后您需要使用与MSVC一起分发的lib.exe,例如:

lib /def:your_dll.def

然后,会有一个来自lib.exe的your_dll.lib文件.(假设you_dll.dll与your_dll.def位于同一目录中).

目前,我可以在我的MSVC项目中使用*.lib并正确链接dll,但是我收到了运行时错误.无论如何,这样的工作使你的联系可行.


Ami*_*yan 5

介绍

用不同的编译器创建的目标文件和静态库,甚至是同一个编译器的显着不同版本,通常不能链接在一起。这个问题不是 MinGW 特有的:许多其他编译器是相互不兼容的。如果可以的话,使用相同版本的相同编译器从源代码构建所有内容。

Dll 的略有不同。有时,您可以将使用一个编译器构建的 DLL 链接到使用另一个编译器编译的应用程序。如果 DLL 是用 C 编写的,即使应用程序是用 C++ 编写的,这也很有效。例如,MinGW C++ 程序通常链接到 Windows 提供的 C 运行时库。用 C++ 编写的 DLL 也可以工作,只要您仅通过使用 extern "C" 声明的 C 接口与它们通信。如果不这样做,您可能会收到链接器错误,因为不同的编译器对 C++ 名称的处理方式不同。

为什么不同的编译器不能互操作

有时人们想知道为什么编译器编写者不只是使用相同的名称修改方案。这可能会使链接成功,但很可能会给您一个在您调用 DLL 时崩溃的程序。真正的链接兼容性需要一个通用的应用程序二进制接口,而名称修改只是众多考虑之一。这是部分清单:--

如果同一系统的两个 C++ 实现使用不同的调用序列,或者在其他方面不兼容,那么使用相同的类型签名编码是不明智的。

实现者传统上故意使用不同的名称修改方案,认为在链接时“只是说不”比让一些简单的代码工作并让问题在运行时出现更好。

尽管 GNU g++ 现在可以链接 MSVC C++ 库,并且可以生成与 MSVC++ 兼容的库/DLL,但这并不意味着由于 C++ 的动态特性,它们将能够在运行时工作。一些可能的原因是:-

  • 可以使用显式 .def 文件规避的简单名称修改问题。
  • 不同的结构对齐问题需要正确的编译器选项(-mms-bitfields,...)。
  • 底层异常和内存模型的根本冲突:--
  1. MSVC DLL 中的 new/delete 或 malloc/free 不会与 Cygwin newlib new/delete 或 malloc/free 合作。根本无法释放在使用不同 new/malloc 的函数中分配的空间。
  2. 由 MSVC DLL 引发的异常不会被 Cygwin 可执行文件捕获,反之亦然。
  3. 缓慢的 GNU SJLJ 异常模型(在 GCC-3.x 和更早版本中使用)与 MSVC++ 模型兼容,但新的 DWARF2 模型(将由 GCC-4.x 使用)将不兼容。

参考:http : //www.mingw.org/wiki/Interoperability_of_Libraries_Created_by_Different_Compiler_Brands