【问题标题】:Compatibility of *.dll *.a *.lib *.def between VisualStudio and gccVisualStudio 和 gcc 之间 *.dll *.a *.lib *.def 的兼容性
【发布时间】:2012-01-30 18:25:42
【问题描述】:

这很令人困惑。我花了很多时间在堆栈等上阅读有关此的帖子。仍然感到困惑。

我正在使用 Qt 和 C++ 进行编码。在 Qt 中,我将 gcc 选项用于编译器。
问题是我尝试过的许多第 3 方库似乎都不起作用。

我是 .dll、.a、.lib、.def 文件和库方案的新手。

问题一:

根据我有限的经验(到目前为止,我已经尝试了 7 或 9 个库),库的供应商很少告诉您 .dll 是用 VisualStudio 还是 gcc 制作的。这增加了很多混乱。他们几乎从未明确说明该库与哪种编译器兼容。所以我会很感激一些关于如何处理这个噩梦的现实生活中的提示。我尝试的几乎所有库都是开源项目。我不会在这里命名,但这些都是众所周知的项目。我确定问题是我缺乏知识...

MinGW 和 gcc 世界

问题2:
据我所知,MinGW gcc Universe 的动态 C++ 库需要这些,对吗?
*.h
*.dll
*.a

问题 3:
不幸的是,.a 文件经常丢失,并且该库无法正常工作。这非常令人困惑。如果 .a 文件丢失,我不走运吗?

问题 4:
如果 *.dll 是用 gcc 制作的,我可以为 MinGW/gcc 生成 .a 文件吗?

问题 5: 如果 *.dll 是用 VisualStudio 制作的,我可以为 MinGW/gcc 生成 .a 文件吗?

问题 6:
是否可能是 *.dll(使用 MinGW/gcc 制作)太旧,不再与新的 MinGW/gcc 兼容?

问题 7:
使用 MinGW/gcc 的 Qt 项目永远不需要 *.lib 文件,对吗?那是 VisualStudio 唯一的东西,对吧?

问题 8:
在使用 MinGW/gcc 的 Qt 项目中,我不需要 *.def 文件来使用 *.dll,对吧?

VisualStudio 世界

问题 9:
据我所知,VisualStudio 的动态 C++ 库需要这些:
*.h
*.dll
*.lib

对吗?同样,问题是 *.lib 文件几乎总是丢失。另外,没有关于库与什么编译器兼容的明确说明。那么我怎么知道它是否仅适用于 VisualStudio?

问题 10:
如果 .lib 文件丢失,我不走运吗?

问题 11:
如果 *.dll 是用 VisualStudio 制作的,我可以为 VisualStudio 生成 .lib 文件吗?怎么样?

问题 12:
如果 *.dll 是用 MinGW/gcc 制作的,我可以为 VisualStudio 生成 .lib 文件吗?怎么样?

问题 13:
是否有可能是 *.dll(使用 VisualStudio 制作)太旧,不再与较新的 VisualStudio 兼容?

问题 14:
如果在 QtCreator 中我选择了 VisualStudio 编译器,那是否与其他人使用 REAL VisualStudio 编译的动态库 100% 兼容?我相信 Qt Creator 中的 VisualStudio 编译器选项是一个假的 VisualStudio 编译器。

问题 15:
如果在 QtCreator 中我选择了 MinGW/gcc 编译器,我可以与其他人用 REAL VisualStudio 编译的 Qt 动态库一起使用吗?

问题 16:
在使用 MinGW/gcc 的 Qt 项目中,我不需要 *.def 文件来使用 *.dll,对吧?

问题 17: 我可以将使用 REAL VisualStudio 制作的 *lib(与 *.dll 和 *.h 一起使用)文件转换为 *.a 文件,以便我可以将 *.a 文件与未修改的 *.dll 和 *.h 一起使用Qt gcc 项目中的文件?

【问题讨论】:

  • 我相信这种复杂性是 Windows 特有的。在 Linux 上使用 Qt 时你不会拥有它!
  • 您可能希望将其分解为多个问题(特别是“如果我有 Y,我可以生成 X”的变体)......可能很多人都可以回答其中一些问题,如果你问他们单独(因为它们与 Qt 完全无关)关于 Windows 链接,您可能会得到更快的响应。话虽如此,我能给你的最短答案是如果你不需要,不要使用 MinGW - VisualStudio 是平台上支持的规范,你将有更好的体验从长远来看(如果在短期内与开源库依赖关系有些痛苦)。
  • -1:一次问 16 个问题。
  • @Nicol:我没有一次问 16 个问题。我将 1 个问题分成不同的小部分,这样细节就不会丢失。我的问题是关于这里的 dll 兼容性。兼容性是一个宏观概念。
  • @Basile - 但是尝试在 Linux 上运行 Visual Studio(使用 wine?)会更加复杂。使用操作系统的本机编译器总是容易得多。 :-)

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


【解决方案1】:

也许值得从头开始,而不是超越自己并描述核心问题。从中可以得出几个问题的答案。

开始是ABI(应用程序二进制接口)。这定义了诸如

  • 如何调用函数,例如哪些参数进入哪些寄存器或它们放在堆栈的哪个位置
  • 如何抛出异常
  • 对象的布局方式,例如“vtable 指针”在哪里,使用什么填充
  • 内置数据类型有多大
  • 如何将函数名称“分解”为符号
  • 类型信息的布局方式
  • 标准库类的布局

大多数平台都定义了 C ABI,但定义了 C++ ABI。结果,编译器定义了自己的 ABI(除了通常存在的 C 内容之外的所有内容)。这会产生在不同编译器之间不兼容的目标文件(有时甚至在同一编译器的版本之间)。

通常,这表现为看起来很奇怪的名称不知何故未定义:不同的 ABI 故意使用不同的名称修饰来防止意外链接无论如何都不会工作的可执行文件。要解决这些问题,最好的办法是使用相同的编译器构建所有组件。

如果您想确定一个库是使用哪个编译器构建的,您可以使用适当的工具查看其内容。我知道您要求使用 Windows,但我只知道 UNIX 工具(它们可能与 MingW 一起可用):

  • nm 查看符号名称(通常与 less 或 grep 一起使用)
  • ar 用于构建或检查库
  • ident 查找嵌入在对象中的特殊字符串
  • 喜欢所有字符串的字符串
  • c++filt 将符号分解到其 C++ 声明中

查看符号通常会识别出编译器生成它们的原因。如果你足够频繁地看到它们,你甚至可以从符号本身中分辨出 ABI。

这方面还有很多,但我已经没有精力了... :-) 无论如何,我认为这回答了上面的几个问题。

【讨论】:

    【解决方案2】:

    在搜索用于使用适用于 Windows 的 Code::Blocks c++ 编译器创建 .a 文件的工具时,我偶然发现了这个问题。 Code:Blocks 使用 MinGW gcc 编译器。我认为它在谷歌上足以验证我的死灵法。

    动态链接库(dll)是混杂的。有些可以以一种使它们很难在创建它们的编程语言和编译器之外使用的方式进行编译。

    然而,DLL 通常是使用干净的 C 接口创建的。在这种情况下,我认为我可以回答您的问题的答案是:

    1:这不是问题。

    2、9:是的

    3、10:没有

    4、11:是的。 MinGW 包含一个工具 (dlltool.exe),它接受一个 .dll 和一个 .def 文件并创建一个 .a 文件 MS VisualStudio 还包括一个工具(我认为它称为 lib.exe)来做同样的事情。 如果你开始使用另一个编译器,你可能会发现他们也有一个工具。 Borlands 编译器有 implib.exe 工具。

    5、12:是(与 4 相同)

    6, 13: pew...我认为 dll 没有过期日期,但它们必须针对正确的操作系统进行编译。

    8, 16:你需要 .def 来制作 .a 或 .lib,如果你没有它,实际上可以从 .dll 中创建它

    【讨论】:

      【解决方案3】:

      DLL 本质上是一个已编译的应用程序 - 只是以函数库的形式而不是 EXE 文件的形式。任何其他应用程序都可以通过声明函数、包含函数的 dll 以及参数和返回值等来使用该 DLL 中的函数。

      如果应用程序是使用“动态链接库”编译的,DLL 必须已经存在于系统上,因此您必须在安装程序中包含必要的 DLL,或者希望它们已经存在于目标计算机上。使用 DLL 可以使您的应用程序的整体尺寸更小。

      创建 DLL 就像创建任何其他应用程序一样 - 您只需将构建定位为 DLL 而不是 EXE 或其他任何东西。

      要创建任何应用程序 - DLL、EXE 或其他 - 您需要必要的源代码和标头。 .h 文件包含函数、数据类型和类等的声明——它们很少包含代码。 .def 很像 .h,但通常是链接器的一组指令。

      当你编译时,一个 .h 或 .c 或任何东西都会变成一个 .obj - 一个目标文件。多个目标文件链接在一起以创建您的 DLL 或 EXE。

      .lib 文件是一个静态库 - 本质上是为链接阶段组合的一堆 .obj 文件(或一个 .obj)。

      .obj 和 .lib 文件的格式可能特定于编译器,它们在编译器之间很少兼容。您必须拥有原始源代码,或者专门为您的编译器制作的 .obj 或 .lib。

      当您选择使用“动态链接库”制作 EXE 时,它会期望它可以使用 DLL。当您选择“静态链接库”时,链接器将在生成 EXE 之前找到它需要的 .lib 文件,而您将不需要这些 DLL。

      【讨论】:

        【解决方案4】:

        问题 1:您应该导入 .h 文件并通过链接器命令链接 .a 文件并将 .dll 复制到您的 .exe 输出附近。

        问题2:你可以通过.def文件制作.a文件

        set PATH=C:\Program Files\CodeBlocks\MinGW\bin;%PATH%
        
        dlltool.exe -d libfftw3-3.def -l libfftw3-3.a
        

        问题3:没有。您可以手动制作.def 文件,然后制作.a 文件。

        问题 4,5:是的

        问题6:我认为这取决于您的硬件和操作系统,而不是您的编译器。

        问题 7:我不知道。

        问题8:你只需要.h.a.dll而不是.def

        问题 9:.lib 文件用于 Visual Studio。

        问题 10:不,您需要 .def.dll 来制作 .lib,如果没有,您可以自己制作 . def

        set PATH=C:\Program Files\Microsoft Visual Studio 12.0\VC\bin;%PATH%
        
        lib /machine:x86 /def:libfftw3-3.def
        

        lib /machine:x64 /def:libfftw3-3.def
        

        问题 11:是的,我在上面告诉过你。

        问题 12:是的

        问题 13:没有。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-08
          • 1970-01-01
          • 2021-07-02
          • 2011-09-19
          • 2017-03-27
          相关资源
          最近更新 更多