VisualStudio和gcc之间*.dll*.a*.lib*.def的兼容性

use*_*167 21 c++ qt gcc mingw visual-c++

这非常令人困惑.我花了很多时间在堆栈上阅读帖子,等等.仍然困惑.

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

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

问题1:

在我有限的经验中(到目前为止我已经尝试了7或9个库),图书馆的供应商很少告诉你.dll是用VisualStudio还是用gcc制作的.这增加了很多困惑.他们几乎从不清楚库兼容的编译器.所以我很欣赏一些如何应对这场噩梦的真实生活技巧.我尝试过的几乎所有库都是OpenSource项目.我不会在这里命名,但这些都是众所周知的项目.我确定问题是我缺乏知识......

MinGW和gcc World

问题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:
我不需要*.def文件在使用MinGW/gcc的Qt项目中使用*.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:
我不需要*.def文件在使用MinGW/gcc的Qt项目中使用*.dll,对吗?

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

Die*_*ühl 15

也许值得从一开始就开始,而不是超越自我并描述核心问题.从这个答案中可以得出几个问题.

起点是ABI(应用程序二进制接口).这定义了类似的东西

  • 如何调用函数,例如哪些参数进入哪些寄存器或堆栈中的哪个位置
  • 如何抛出异常
  • 如何布置对象,例如"vtable指针"所在的位置,使用什么填充
  • 内置数据类型有多大
  • 函数名称如何"损坏"成符号
  • 如何打印类型信息
  • 标准库类的布局
  • 等等

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

通常情况下,这表现为看起来很奇怪的名称,某种程度上是未定义的:不同的ABI故意使用不同的名称修改来防止意外链接无法正常工作的可执行文件.要解决这些问题,最好的办法是使用相同的编译器构建所有组件.

如果要确定构建库的编译器,可以使用适当的工具查看其内容.我意识到你要求Windows,但我只知道UNIX工具(它们可能与MingW一起提供):

  • nm来查看符号名称(通常与less或grep一起)
  • 建立或检查图书馆
  • ident用于查找嵌入在对象中的特殊字符串
  • 字符串喜欢所有字符串
  • c ++ filt将符号解码为C++声明

查看符号通常会产生编译器生成它们的标识.如果你经常看到它们,你甚至可以从符号本身告诉ABI.

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


小智 7

在使用Code :: Blocks c ++ compiler for windows搜索用于创建.a文件的工具时,我偶然发现了这个问题.代码:Blocks使用MinGW gcc编译器.在谷歌这是足够高,以验证我的神秘感.

动态链接库(dll)是混合的.有些可以编译,使得它们很难在编程语言和创建它们的编译器之外使用.

但是,通常使用干净的C接口创建dll.在这种情况下,我认为我能回答的问题的答案是:

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创建的.


Mat*_*t H 5

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。