从MinGW链接到MSVC DLL

40

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

在Windows上编译并不那么容易。 他们是使用Microsoft Visual Studio构建的库,而我们使用MinGW。 我已经阅读了MinGW FAQ,并遇到了下面的问题。 这个库全部都是C ++,所以我的第一个问题是:这真的可能吗?

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

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

使用wiki中描述的第二种方法,我在dll上运行了pexport和dlltool以获得.a文档库,但是它产生了相同的“未定义引用”错误。

顺便说一句:我已经阅读了下面的讨论。 它留下了某些不确定性,是否可能,并且鉴于MinGW Wiki页面,似乎应该是可行的。 如果不可能,那就是我需要知道的全部内容。 如果可以做到,我想知道如何实现。

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

谢谢!


http://www.mingw.org/wiki/DLL 可能对您有用。 - rogerdpack
1
那么 https://github.com/Chuyu-Team/VC-LTL 怎么样? - BladeMight
4个回答

31

你做不到这一点。他们从其dll中导出了C ++类,而不是C函数。区别在于,C ++函数始终以特定于特定编译器版本的缩写形式导出名称。

他们的dll仅可由msvc在该形式下使用,并且可能甚至无法在不同版本的msvc之间工作,因为Microsoft以前已更改过它们的缩写方案。

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


1
谢谢,这正是我在寻找的确认。他们确实有一个C接口,我正在考虑使用它,但它比C++中可用的要弱得多。我也在推动他们发布MinGW版本。 - IndigoFire
6
我更喜欢所有软件的mingw版本,因为它只需要使用普遍可用的mstcrt.dll作为C运行时依赖项,而不是特定于Visual Studio版本的运行时文件如msvcr70.dll、msvcr71.dll、msvcr80.dll、msvcr90.dll以及现在的msvcr100.dll,这样部署就变得非常简单了。 - Chris Becke

4

我几乎可以确定,您无法像那样跨编译器链接C++库。我曾经尝试过,非常努力,但这是很久以前的事情,我不记得细节了。我认为对于C库来说是可能的,但需要使用许多技巧。


1

我想在这里加上我的两分钱。

当你想要链接到MSVC中的dll时,你需要链接到一个包含函数存根的.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 mangler/demangler。

0
在Windows中使用DLL,您需要链接到一个导入库(而不是DLL本身)。导入库通常具有扩展名.lib(就像静态库一样)。如果您下载Windows SDK,则会获得所有系统DLL的导入库。
从您的问题来看,似乎您可能混淆了.dll和.lib。您确定reimp不会以DLL作为输入并生成与MinGW兼容的.LIB导入库吗?
我刚在维基百科上查了一下MinGW。根据该文章,MinGW附带可再分发的导入库。

2
根据MinGW维基,reimp需要一个导入库。尽管我尝试过对DLL运行它,但也不起作用。 - IndigoFire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接