我正在使用GNU binutils在Windows上构build一个dll。
我知道DLL可以加载时,可执行文件加载或运行时(使用LoadLibrary API调用)。
对于加载时加载,我似乎只需要dll文件:不需要.a,.lib或.def文件。 我想知道这些文件格式代表什么和他们的目的是什么。
我所知道的和一些具体的问题:
.a是Unix上通常用于静态库的扩展。 .a文件是使用GNU ld的–out-implib选项生成的。 据说这是一个“import图书馆”,够公平的。 现在的问题是“如果链接时不需要导入库,对我有什么好处?”
.lib是在Windows上用于静态库的扩展,根据维基百科,它也被用作windows下的“导入库”,所以我强烈怀疑它们只是binutils调用.a文件的另一个名称。 真假 ?
我可以find所有页面.def文件列出了导出的DLL符号。 这与“import图书馆”应该做什么有些类似?
此外,我在这里读到,使用.def文件是手动指定源文件中的导出(我所做的)的替代方法。 但我也记得阅读(无法find参考).def文件提供一个索引( 序数 )到导出的符号,允许更快的运行时加载。 是这样吗 ?
Linux上的静态库具有.a
文件扩展名。 Windows上的静态库具有.lib
文件扩展名。 Windows上的动态库具有.dll
扩展名; 为了链接到一个DLL,一个导入库是必需的。 导入库是一个静态库。 它包含加载DLL所需的代码。 现在你正在使用GCC(而不是cl.exe
)在Windows上编译。 GCC对于导入库有另一个文件扩展名约定,它应该被称为* .dll.a或者* .a“,正如文档中提到的--out-implib
所--out-implib
。
导入库(具有MSVC的.lib
或具有GCC的.dll.a
) 是静态库:它们包含加载DLL的代码。 我有一天有同样的问题。
DLL可能具有导出的函数和不导出的函数。 导入库必须知道哪些函数被导出,哪些不是。 告诉它的一个手段是一个DEF文件。
当生成DLL时,链接器使用.def文件创建一个导出(.exp)文件和一个导入库(.lib)文件。 链接器然后使用导出文件来构建DLL文件。 在构建时隐式链接到导入库的DLL链接的可执行文件。 – MSDN:使用DEF文件从DLL导出
另请参阅MSDN:通过序号而非名称从DLL导出函数 ,应该通过索引或序号来回答最后一个关于导出的问题。