【问题标题】:How to bundle a static library with an import library (or two static libraries) with lib.exe?如何使用 lib.exe 将静态库与导入库(或两个静态库)捆绑在一起?
【发布时间】:2023-01-20 22:40:23
【问题描述】:

在 Windows 上为 DLL 导入库是一件很奇怪的事情。他们提供链接器在生成的 PE 文件中创建导入存根所需的胶水(命名为 .dll.exe 或其他名称)。

This Q&A provides details 关于如何在 Unix 端捆绑两个静态库。如何使用 Visual C++ 在 Windows 上实现相同的目的?

另外,有没有办法结合静态库和导入库?

【问题讨论】:

    标签: windows visual-c++ static-libraries dllimport


    【解决方案1】:

    虽然这里的其他问答会让您有不同的想法,甚至微软似乎也没有记录这种可能性,但我已经看到了我称之为混合静态/导入库的东西,它分布在某个硬件供应商的 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 符号,我们可能会很幸运。

    使用这个混合静态/导入库将要工作,但如果你删除点点滴滴,最好删除全部立即从中导入库零件。你可以在技术上重新开始。

    一些警告

    这很可能不是事物的预期用途。所示方法有局限性,需要您知道自己在做什么:

    1. 创建组合(或混合)库的各个部分不得有符号名称冲突,除非符号名称明确向链接器提供完全相同的东西(来自任意导入库的__NULL_IMPORT_DESCRIPTOR 应该是无害的,例如)
      • 目标文件的名称和路径也不能冲突
    2. 以后的软件可能必须使用较新版本的导入库,因此您可能会发现自己无论如何都要拆开混合库
    3. 即使您知道自己在做什么,即使您对所有变量有类似 Raymond-Chen 的概览,也很有可能你仍然不想使用这个.是因为发现将导入库组合到静态库中是完全令人惊讶的事实。或者是因为您的继任者或未来的开发人员可能不知道所有细节,并且“雪上加霜”您忘记记录您的非正统行为......

      更多信息

      • 由 Visual C++ 创建和处理的 .lib 文件在技术上也是只是ar archives,在 Unix 上很常见
        • 您可以使用 7-Zip 等工具来解压和检查它们(重新打包它们通常更难)。
          • 相反,您可以在 Linux 上使用 ar,例如,处理源自 Windows 的 .lib 文件(由于路径分隔符等,有一些注意事项)
        • 虽然在 Unix 端,包含的 .o 文件本身通常是 ELF 文件,但对于 Visual C++,包含的 .obj 文件是 COFF。
        • 您可以使用objconvBinutils 等工具来操作这些文件。后者必须专门构建以支持 COFF 和与您的特定 .lib 文件相关的体系结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多