将多个DLL合并成一个

4

我想知道是否有可能将多个DLL合并成一个。我目前正在开发一项依赖于许多动态链接库的C++项目,因此是否有可能将它们合并成一个DLL文件?如果可以,应该如何操作?


1
你能否澄清一下,这些DLL的源代码是否可用? - ysth
我确实有这些DLL的源代码。 - Greg Treleaven
3个回答

5

是的,我有这些DLL的源代码。

只需将所有DLL项目的源文件合并到一个DLL项目中即可?

如果您有多个*.def文件(每个项目一个),则将它们合并成一个*.def文件。


2
实际上不行。理论上,如果你非常想做,你可以像拆卸所有的文件一样,将它们重新组装成目标文件,然后将这些目标文件重新链接到一个大的DLL中。但要让这个方法真正起作用通常是很困难的——可能会出现冲突的符号名称,需要花费相当大的力气去解决。
一个比较简洁的方法是将所有的DLL打包成一个zip文件(或者其他你喜欢的格式),然后编写一个小程序将它们解压到临时目录,运行主程序,最后从该目录中删除DLL。但这种方法也有一些问题(例如,如果机器在运行过程中崩溃/断电/发生其他故障,则会留下文件的副本)。
编辑:由于你有源代码,使用它将所有代码构建为单个DLL更加合理。大部分情况下,只需将所有源文件添加到一个创建单个DLL输出的项目中即可。你可能会(很容易地)遇到一些符号冲突。有了源代码,处理这个问题的明显方法是将其放入命名空间中。

1

这绝对不是不可行的。Dll格式包含了您需要将多个dll中的代码和数据合并成一个,并重新定位生成的代码所需的所有信息。

然而,我想不出任何工具链的标准功能包括此功能。


一般情况下,这并不是真正可能的,你会有很多重复的符号。CRT 的部分(如果您静态链接它,则全部)将在两个进程中都存在,可能会进行优化,因此也不是完全相同的副本。 - Blindy
1
那将是重新链接。没有需要在名称级别上操作来将两个dll粘合在一起。你要做的就是连接或创建重复(重命名).text、.sdata等节(这些节的名称实际上并不相关)。然后处理重定位表——根据合并节的新基地址进行调整。符号名称与此无关(除非你试图修复调试信息)。 - Chris Becke
如果其中一个合并的DLL依赖于另一个DLL,您还必须清理导入地址表。您不能依赖于自己。这是一个名称级别的操作;您必须通过作用域(DLL)和符号名称匹配导入和导出条目。 - MSalters
我承认我没有考虑到交叉依赖。但是,由于名称在合并的(或外部的)dll中可以明确解析为函数,因此仍然不存在名称冲突。 - Chris Becke
这一切都没有意义。楼主有源代码并且可以(而且应该(确实必须))构建一个合并的dll。 - Chris Becke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接