【问题标题】:Linking to MSVC DLL from MinGW从 MinGW 链接到 MSVC DLL
【发布时间】:2011-01-29 04:45:20
【问题描述】:

我正在尝试将 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++

谢谢!

【问题讨论】:

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


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢,这正是我正在寻找的确认信息。他们确实有一个 c 接口,我正在考虑使用它,但它的功能远不如 C++ 中可用的强大。我也在推动他们为 MinGW 发布。
  • 我确实更喜欢 mingw 版本的所有内容,因为当 c-runtime 依赖项是普遍可用的 msvcrt.dll,而不是 Visual Studio 版本特定的运行时 msvcr70.dll 时,它使部署变得非常简单、msvcr71.dll、msvcr80.dll、msvcr90.dll 和现在的 msvcr100.dll。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    我刚刚在 Wikipedia 上查找了 MinGW。根据那篇文章,MinGW 带有可再分发的导入库。

    【讨论】:

    • 基于 MinGW wiki,reimp 需要一个导入库。虽然我确实尝试过,但对 DLL 运行它也不起作用。
    【解决方案4】:

    只是想我会在这里加两分钱。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多