查找有关dlltool的信息--添加间接(-a)



我正在寻找有关dlltool的--add间接选项的更多信息。您什么时候使用此选项?它做什么?

有关此选项的binutils帮助信息:

-a
--add-indirect

指定dlltool在创建导出文件时应添加允许引用导出函数的部分使用导入库。不管那是什么意思!

首先,让我们弄清楚什么是导出文件。创建DLL需要导出文件。该文件与构成DLL主体(即函数、类等)的对象文件(由编译器生成)链接,并处理DLL与外部世界之间的接口。这是一个二进制文件,当创建或读取*.def文件时,可以通过向dlltool提供-e选项来创建。

您必须理解的下一个术语是导入库。某些使用者应用程序使用DLL的方法之一是将此应用程序链接到DLL,以便使用者可以使用从DLL导出的所有功能。这种到DLL的链接通常是通过链接到导入库来完成的,该导入库本质上是一个辅助静态库,包含导入地址表(IAT),该表允许消费者引用所有DLL导出的功能。例如,每个引用的DLL函数在IAT中都包含自己的条目。在运行时,IAT填充有适当的地址,这些地址直接指向单独加载的DLL中的相应函数。

现在让我们手动用dlltoolgcc创建一个DLL,让您了解正在发生的事情:

gcc -c library.c

产生library.o

dlltool -e exports.o -l library.dll.a library.o

生成导出文件exports.o和导入库library.dll.a.dll.a是GCC生成的导入库的常规后缀,它强调导入库实际上与.a是静态的,但与.dll针对DLL),

gcc library.o exports.o -o library.dll

产生library.dll

gcc consumer.o library.dll.a -o consumer

生成针对CCD_ 15链接的可执行CCD_。

注意:以上是创建DLL的手动过程,不建议在生产中这样做,因为GCC将所有逻辑封装在一个优化的调用中:

gcc -shared -o library.dll library.o -Wl,--out-implib,library.dll.a

回到正轨,既然我们知道了基本的术语和目的,我们就可以很容易地解释--add-indirect:的帮助中所写的内容

指定dlltool在创建导出文件时应添加允许引用导出函数的部分使用导入库。不管那是什么意思!

让我们把它应用到前面的例子中。在这种情况下,exports.o将已经包含IAT,因此生成的library.dll也将包含该信息,因此我们不需要导入库library.dll.a,因为现在我们可以直接链接到library.dll本身:

gcc consumer.o library.dll -o consumer

它是否有用是一个很主观的问题。我想从我们(程序员/用户)的角度来看,这是非常无用的,因为DLL的创建和链接无论如何都不应该显式地完成(即通过直接调用dlltool),而应该通过GCC前端完成(如上所述)。从构建工具链(如GCC本身)等开发工具的角度来看,这可能是有用的,因为GCC本身实际上可以在幕后使用类似于上述示例的东西来执行gcc -shared -o library.dll ...

最后,通常不鼓励直接链接DLL。尽管它与最新版本的MinGW/MinGW-w64配合得很好,但它过去也有漏洞。此外,如果禁用了伪重定位,那么与DLL的直接链接可能会导致某些运行时问题。此外,这是MSVC将消费者与DLL链接的官方方式,即如果没有导入库,MSVC根本无法进行链接,这也可能是您应该始终使用导入库的原因。请记住,DLL与Linux上的共享对象(SO)不同:它们的用例是相同的,但它们的实现基于不同的技术。

相关内容

  • 没有找到相关文章

最新更新