我正在使用GNU binutils从Windows上的程序集构建一个dll。
我知道可以在加载可执行文件时或在运行时加载dll(使用LoadLibrary api调用)。
对于加载时加载,我似乎只需要dll文件:不需要.a,.lib或.def文件。我想知道这些文件格式代表什么以及它们服务的目的是什么。
我所知道的和一些具体问题:
.a是Unix上通常用于静态库的扩展。 .a文件是使用GNU ld的--out-implib选项生成的。它被认为是一个“进口图书馆”,足够公平。那么问题是“如果我在链接时不需要它,对我来说有什么用处?”
.lib是Windows上用于静态库的扩展,根据维基百科,它也被用作windows下的“导入库”,所以我强烈怀疑它们只是binutils调用的另一个名称。一个文件。是/否?
我可以找到的所有页面都指出.def文件列出了dll的导出符号。是不是有点像“导入库”应该做的那样?
此外,我读到here使用.def文件是在源文件中手动指定导出的替代方法(我做过)。但我还记得读取(找不到引用).def文件为导出的符号提供索引(ordinal),允许更快的运行时加载。是这样吗?
答案 0 :(得分:50)
Linux上的静态库具有.a
文件扩展名。 Windows上的静态库具有.lib
文件扩展名。 Windows上的动态库具有.dll
扩展名;为了链接DLL,需要导入库。导入库是一个静态库。它包含加载DLL所需的代码。现在你正在使用GCC(而不是cl.exe
)在Windows上编译。 GCC对导入库有另一个文件扩展名约定,它应该被称为“* .dll.a或* .a”,如你所提到的doc for the --out-implib
中所述。
导入库(.lib
与MSVC或.dll.a
与GCC)是静态库:它们包含加载DLL的代码。 I had the same question the other day.
DLL可能具有导出的功能和未导出的功能。导入库必须知道哪些函数是导出的,哪些不是。告诉它的一种方法是DEF文件。
构建DLL时,链接器使用 用于创建导出的.def文件 (.exp)文件和导入库 (.lib)文件。然后链接器使用 导出文件以构建DLL文件。 隐式链接到的可执行文件 DLL链接到导入库 什么时候建造。 - MSDN: Exporting from a DLL Using DEF Files
另请参阅MSDN: Exporting Functions from a DLL by Ordinal Rather Than by Name,我们应该一起回答您关于按索引或序号出口的最后一个问题。