C++ 从 MinGW 链接到 MSVC DLL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2472924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:34:39  来源:igfitidea点击:

Linking to MSVC DLL from MinGW

c++gccg++mingwvisual-c++

提问by IndigoFire

I'm trying to link the LizardTech GeoExpress DSDK into my own application. I use gcc so that we can compile on for platforms. On Linux and Mac this works easily: they provide a static library (libltidsdk.a) and headers and all that we have to do is use them.

我正在尝试将 LizardTech GeoExpress DSDK 链接到我自己的应用程序中。我使用 gcc 以便我们可以针对平台进行编译。在 Linux 和 Mac 上,这很容易:它们提供了一个静态库 ( libltidsdk.a) 和头文件,我们所要做的就是使用它们。

Compiling for windows isn't so easy. They've built the library using Microsoft Visual Studio, and we use MinGW. I've read the MinGW FAQ, and I'm running into the problems below. The library is all C++, so my first question: is this even possible?

为 Windows 编译并不那么容易。他们使用 Microsoft Visual Studio 构建了库,我们使用 MinGW。我已阅读 MinGW 常见问题解答,但遇到了以下问题。该库全是 C++,所以我的第一个问题是:这甚至可能吗?

Just linking against the dll as provided yields "undefined reference" errors for all of the C++ calls (constructors, desctructors, methods, etc).

仅根据提供的 dll 链接会产生所有 C++ 调用(构造函数、析构函数、方法等)的“未定义引用”错误。

Based on the MinGW Wiki: http://www.mingw.org/wiki/MSVC%5Fand%5FMinGW%5FDLLsI should be able to use the utility reimpto convert a .lib into something useable. I've tried all of the .lib files provided by LizardTech, and they all give "invalid or corrupt import library". I've tried both version 0.4 and 0.3 of the reimp utility.

基于 MinGW Wiki:http: //www.mingw.org/wiki/MSVC%5Fand%5FMinGW%5FDLLs我应该能够使用该实用程序reimp将 .lib 转换为可用的东西。我已经尝试了 LizardTech 提供的所有 .lib 文件,它们都给出了“无效或损坏的导入库”。我已经尝试了 reimp 实用程序的 0.4 和 0.3 版。

Using the second method described in the wiki, I've run pexport and dlltool over the dll to get a .a archive, but that produces the same undefined references.

使用 wiki 中描述的第二种方法,我在 dll 上运行 pexport 和 dlltool 以获取 .a 存档,但这会产生相同的未定义引用。

BTW: I have read the discussion below. It left some ambiguity as to whether this is possible, and given the MinGW Wiki page it seems like this should be doable. If it is impossible, that's all I need to know. If it can be done, I'd like to know how I can get this to happen.

BTW:我已经阅读了下面的讨论。关于这是否可行,它留下了一些歧义,鉴于 MinGW Wiki 页面,这似乎应该是可行的。如果这是不可能的,那就是我需要知道的全部。如果可以的话,我想知道我怎样才能做到这一点。

How to link to VS2008 generated .libs from g++

如何从 g++ 链接到 VS2008 生成的 .libs

Thanks!

谢谢!

采纳答案by Chris Becke

You can't do this. They have exported C++ classes from their dll, rather than C-functions. The difference is, c++ functions are always exported with names in a mangled form that is specific to a particular version of the compiler.

你不能这样做。他们从他们的 dll 中导出了 C++ 类,而不是 C 函数。不同之处在于,c++ 函数总是以特定于特定编译器版本的重整形式导出名称。

Their dll is usable by msvc only in that form, and will probably not even work between different versions of msvc, as Microsoft have changed their mangling scheme before.

他们的 dll 只能以这种形式被 msvc 使用,甚至可能无法在不同版本的 msvc 之间工作,因为微软之前已经改变了他们的修改方案。

If you have any leverage, you need to get them to change their evil ways. Otherwise you will need to use MSVC to write a shim dll, that will import all the classes, and re-export them via c functions that return interfaces.

如果你有任何筹码,你需要让他们改变他们的邪恶方式。否则,您将需要使用 MSVC 编写一个 shim dll,它将导入所有类,并通过返回接口的 c 函数重新导出它们。

回答by Chris H

I'm almost certain that you can't link C++ libraries across compilers like that. I've tried, really hard, but it was a long time ago and I don't remember the details. i think for C libraries is possible, with a lot of hacks.

几乎可以肯定你不能像这样跨编译器链接 C++ 库。我试过,真的很努力,但那是很久以前的事了,我不记得细节了。我认为 C 库是可能的,有很多技巧。

回答by Adrian McCarthy

To use a DLL in Windows, you link against an import library (not the DLL itself). Import libraries typically have the extension .lib (just like static libraries). If you download the Windows SDK, you'll get import libraries for all of the system DLLs.

要在 Windows 中使用 DLL,您需要链接一个导入库(而不是 DLL 本身)。导入库通常具有扩展名 .lib(就像静态库一样)。如果您下载 Windows SDK,您将获得所有系统 DLL 的导入库。

From your question, it sounds like you might have mixed up the .dll with the .lib. Are you sure reimp doesn't take a DLL as input and make a .LIB import library that's compatible with MinGW?

从您的问题来看,听起来您可能将 .dll 与 .lib 混淆了。您确定 reimp 不会将 DLL 作为输入并制作与 MinGW 兼容的 .LIB 导入库吗?

I just looked up with MinGW is on Wikipedia. According to that article, MinGW comes with redistributable import libraries.

我刚刚在维基百科上查了一下 MinGW。根据那篇文章,MinGW 带有可重新分发的导入库。

回答by Christopher Bekesi

Just thought I'd add my two cents here.

只是想我会在这里加上我的两美分。

When you want to link against a dll in MSVC, what you do is linking against a .lib which contains function stubs that in turn calls the corresponding function in the .dll (an extra indirection with "__imp__" added to the mangled name). GCC doesn't do that, because in theory you can easily link directly to the dll if the functions are exposed by the export table. You can tell GCC in MinGW to look in the dll directly using -l . It is true that the C++ naming scheme varies across a few different versions of MSVC but not across all of them. They are consistent across most of the versions and extensions are added as new features gets implemented.

当您想链接到 MSVC 中的 dll 时,您要做的是链接到包含函数存根的 .lib,该存根又调用 .dll 中的相应函数(一个额外的间接引用,将“__imp__”添加到损坏的名称中)。GCC 不会这样做,因为理论上如果导出表公开了函数,您可以轻松地直接链接到 dll。您可以告诉 MinGW 中的 GCC 使用 -l 直接查看 dll。确实,C++ 命名方案在几个不同版本的 MSVC 中有所不同,但并非在所有版本中都不同。它们在大多数版本中都是一致的,并且随着新功能的实现而添加了扩展。

MinGW however uses the GCC name mangling scheme, that includes searching for external symbols, so it doesn't recognize the MSVC mangled names. The linker could easily solve this by remangling the external symbols to match MSVC and then check again if there is a match. Maybe this will be implemented someday. I've solved this in my own programming language in a similar way but that of course includes my own linker.

然而,MinGW 使用 GCC 名称重整方案,其中包括搜索外部符号,因此它无法识别 MSVC 重整名称。链接器可以通过重新组合外部符号以匹配 MSVC 然后再次检查是否匹配来轻松解决此问题。也许有一天这会实施。我已经用我自己的编程语言以类似的方式解决了这个问题,但这当然包括我自己的链接器。

It is fully possible to provide GCC in MinGW with a .lib, simply specify it on the commandline the same way you specify the source files; gcc -o test.cpp main.cpp external.lib… This will provide the linker with the mangled names it should look for. MinGW is capable of dealing with MSVC mangled names too, it even has its own MSVC mangler/demangler in libmangle.

完全可以在 MinGW 中为 GCC 提供 .lib,只需在命令行上指定它,就像指定源文件一样;gcc -o test.cpp main.cpp external.lib... 这将为链接器提供它应该寻找的错误名称。MinGW 也能够处理 MSVC 损坏的名称,它甚至在 libmangle 中有自己的 MSVC mangler/demangler。