我正在尝试将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++
谢谢!
答案 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。