从MinGW链接到MSVC DLL

时间:2010-03-18 19:52:09

标签: c++ gcc g++ mingw visual-c++

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

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

只需链接到所提供的dll,就会产生所有C ++调用(构造函数,析构函数,方法等)的“未定义引用”错误。

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

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

顺便说一句:我已经阅读了下面的讨论。它是否有可能留下一些含糊不清的地方,并且考虑到MinGW Wiki页面,它似乎应该是可行的。如果不可能,那就是我需要知道的全部内容。如果可以做到,我想知道如何实现这一目标。

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

谢谢!

4 个答案:

答案 0 :(得分:23)

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

msdc只能以这种形式使用它们的dll,并且可能甚至不能在不同版本的msvc之间工作,因为Microsoft之前已经改变了它们的修改方案。

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

答案 1 :(得分:3)

我几乎确定你不能在这样的编译器之间链接C ++库。我尝试过,真的很难,但很久以前,我不记得细节了。我认为C库是可能的,有很多黑客攻击。

答案 2 :(得分:0)

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

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

我刚看完MinGW就在维基百科上。根据那篇文章,MinGW带有可再发行的导入库。

答案 3 :(得分:0)

只是以为我要在这里加两分钱。

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

但是

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

完全有可能为MinGW中的GCC提供.lib,只需在命令行中以与指定源文件相同的方式指定它即可; gcc -o test.cpp main.cpp external.lib ……这将为链接程序提供应查找的错误名称。 MinGW也能够处理MSVC异常名称,它甚至在libmangle中也具有自己的MSVC异常/ demangler。