将MinGW程序与MSVC静态库链接时发出警告

时间:2016-06-06 10:34:23

标签: c visual-c++ mingw static-linking abi

我有一个MinGW64 C ++程序,我需要将它链接到作为目标文件提供的MSVC 64位静态C库(obj)

我使用:

将其转换为.a
ar rcs libtest.a test.obj

这创建了没有警告的静态库

当我链接程序时,我得到:

  

警告:在def文件末尾损坏.drectve

但链接的程序似乎运行正常(多长时间?)

我怎样摆脱这个警告?该库不是开源的,由商业供应商提供。如果需要,我可以让他用其他标志编译它。

1 个答案:

答案 0 :(得分:0)

  

我使用:

将其转换为.a
ar rcs libtest.a test.obj

实际上,这不是以任何方式转换 test.obj。一个静态库 (.a)只是一个目标文件存档和一个目录 链接器可以通过它搜索它。

您的ar命令创建一个仅包含test.obj的静态库。 如果您知道MinGW64链接需要test.obj则没有 将它单独放入图书馆。链接器将简单地提取test.obj 从库中添加它到链接,所以你也可以 直接链接test.obj

如果你这样做,MinGW64的GNU链接器将链接它并将完全发射 从静态库链接时得到的相同警告。这个 告诉你,引发警告的是在目标文件中,它是这样的: -

PE对象文件格式提供了传统编译器的“abitrary信息”部分 标签.drectve并用于嵌入它想要与链接器通信的指令, 它将阅读并遵守它们 - 如果可以的话。

MSVC使用.drectve部分,当然,编写链接器指令 MS链接器的意义,例如

Microsoft (R) COFF/PE Dumper Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file hw.obj

File Type: COFF OBJECT

   Linker Directives
   -----------------
   /DEFAULTLIB:LIBCMT
   /DEFAULTLIB:OLDNAMES

  Summary

           C .data
          64 .debug$S
          2F .drectve
          12 .text$mn

它们对GNU链接器没有任何意义,所以它警告说 .drectve部分已损坏。

你可以取消警告吗?

不,没有这样的选择。

您能否让供应商以不同的方式为您编制test.obj来阻止警告?

取决于MSVC生成的“损坏的”.drectve部分的内容(哪个 你可以发现dumpbin),可能有一个MSVC编译器选项来抑制 它的一代。但后来更多。

链接安全吗?

嗯,您的链接器认为目标文件完全损坏的事实应该可以控制期望。 MinGW64无法保证您可以安全地链接MSVC的目标文件 或者根本没有。 MSVC不保证您可以将其目标文件与任何其他文件链接。 Windows不规范静态链接 不同的编译器的目标文件。实际上,您可以将test.obj链接到您的其他GCC C ++应用程序中,因为 所有目标文件都是Windows COFF pe-x86-64对象文件,例如您的链接器能够 链接在一起,并愉快地,test.obj包含C,而不是C ++,符号,所以不兼容 MS和GCC C ++的名称修改并没有阻止它。如果程序有效,那就是可以保证的 你将会得到它的安全性。

如果你真的想要更多的保证 - 或者只是想要一个由test.obj制作的二进制文件 您可以在没有警告的情况下链接到您的应用程序 - 然后尝试从test.obj创建 DLL

    g++ -shared -o test.dll test.obj

当您执行该一次性步骤时,可以预期相同的链接警告,但如果不是这样的话 成功然后test.dll可以链接到您的应用程序,至少保证ABI兼容性, 因为它是一个DLL。

这让我们回到了使用不同的编译选项。如果供应商将编译 test.obj根据您的要求,然后要求供应商将其编译为DLL 。对于Windows, DLL是ABI兼容性的标准单元。