虽然这里的其他问答会让您有不同的想法,甚至微软似乎也没有记录这种可能性,但我已经看到了我称之为混合静态/导入库的东西,它分布在某个硬件供应商的 SDK 中。
通常,使用库管理器 (lib.exe) 组合/捆绑两个静态库很简单, 顺便说一下, 只是调用 link.exe /lib 并传递任何参数的浅层包装器。你会像这样使用它:
> lib.exe /nologo /out:combined.lib static1.lib static2.lib
简单的。但逆向过程并不那么简单,因为您需要指定每个 .obj 文件,包括它们在 lib.exe /remove:... 中的相对路径。所以基本上不知道.obj最初属于哪个静态库是先决条件。
如果你想组合一个静态库和两个导入库,你可以像这样使用lib.exe:
> lib.exe /nologo /out:hybrid.lib static.lib dll1.lib dll2.lib
dll2.lib(dll2.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in dll1.lib(dll1.dll); second definition ignored
在这种特殊情况下,警告是良性的,可以忽略,但它做告诉我们一件事:如果多次定义相同的符号,合并两个库可能会导致问题.我建议绝不到/ignore:...这个警告曾经,如果您遵循此问答中的任何示例。
此外,您不能将包含相同路径的两个库合并到 .obj 文件。
但是,将导入库的捆绑反转为混合静态/导入库是更多的直截了当,因为我们应该删除以摆脱导入库的成员名称是 DLL 名称。
所以我们可以这样做:
> lib /nologo /remove:dll1.dll hybrid.lib
但是这里有一个潜在的问题,我从来没有尝试过这种情况的所有变化。还记得我们是如何得到这个警告的吗?:
dll2.lib(dll2.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in dll1.lib(dll1.dll); second definition ignored
如果我现在删除只要dll1.dll 成员,我们的hybrid.lib 中可能没有更多的 __NULL_IMPORT_DESCRIPTOR 了。按理说,一旦我们尝试使用这个混合库构建 PE 文件,link.exe 就会向我们吐槽。但如果命令行上有其他导入库提供可用的 __NULL_IMPORT_DESCRIPTOR 符号,我们可能会很幸运。
使用这个混合静态/导入库将要工作,但如果你删除点点滴滴,最好删除全部立即从中导入库零件。你可以在技术上重新开始。
一些警告
这很可能不是事物的预期用途。所示方法有局限性,需要您知道自己在做什么:
- 创建组合(或混合)库的各个部分不得有符号名称冲突,除非符号名称明确向链接器提供完全相同的东西(来自任意导入库的
__NULL_IMPORT_DESCRIPTOR 应该是无害的,例如)
- 以后的软件可能必须使用较新版本的导入库,因此您可能会发现自己无论如何都要拆开混合库
- 即使您知道自己在做什么,即使您对所有变量有类似 Raymond-Chen 的概览,也很有可能你仍然不想使用这个.是因为发现将导入库组合到静态库中是完全令人惊讶的事实。或者是因为您的继任者或未来的开发人员可能不知道所有细节,并且“雪上加霜”您忘记记录您的非正统行为......
更多信息
- 由 Visual C++ 创建和处理的
.lib 文件在技术上也是只是ar archives,在 Unix 上很常见
- 您可以使用 7-Zip 等工具来解压和检查它们(重新打包它们通常更难)。
- 相反,您可以在 Linux 上使用
ar,例如,处理源自 Windows 的 .lib 文件(由于路径分隔符等,有一些注意事项)
- 虽然在 Unix 端,包含的
.o 文件本身通常是 ELF 文件,但对于 Visual C++,包含的 .obj 文件是 COFF。
- 您可以使用
objconv 或Binutils 等工具来操作这些文件。后者必须专门构建以支持 COFF 和与您的特定 .lib 文件相关的体系结构。