【问题标题】:Static library with dependencies具有依赖关系的静态库
【发布时间】:2011-06-06 12:36:27
【问题描述】:

e.exe 链接到我的自定义静态库c.lib,它使用w.dll 中定义的 Win32 API。 w.dll位于C:\Windows\System32,其导入库为w.lib,位于Windows SDK目录下。 Shell w.libc.libe.exe 项目中被列为附加依赖? (e.exe 在这两种情况下都成功构建。)最佳实践是什么,为什么?我猜e.exe 不应该知道w.lib

c.lib 仅供一组开发人员共享(不发送给客户)。

测试:我使用 VS2008 和 dumpbin 实用程序对这两种情况进行了测试,结果如下:

  • 案例 1:w.libc.lib 项目中添加为附加依赖项

dumpbin /archivemembers c.lib 输出将w.dll 中的偏移量和来自c.lib 项目的 .obj 文件作为存档成员列出。

  • 案例 2:w.lib 没有作为附加依赖项添加到 c.lib 中,而是添加到 e.exe 项目中:

这一次,dumpbin 输出只包含c.lib 的.obj 文件,c.lib 的大小比情况1 小

c.lib 在这两种情况下都被添加为w.exe 项目中的附加依赖项。)

注意:我在这里使用 w.libw.dll 作为 Windows 库的虚构通用名称,但它们可能是例如Userenv.lib 和 Userenv.dll 或 Version.lib 和 Version.dll...

【问题讨论】:

    标签: c++ visual-studio winapi static-libraries


    【解决方案1】:

    库未链接,因此任何使用 .lib 的项目也需要其依赖项。

    基本上 .lib 在链接期间被“复制”到您的 exe 中。

    如果您想避免您的用户显式链接 w.lib,将 c.lib 转换为 dll,dll 已链接,并且您在构建期间不需要它们的依赖项。

    【讨论】:

    • 我知道link.exe 不会解析外部引用,而只是压缩一组obj 文件以创建静态库。我的问题是关于编译时的依赖关系——案例 1 表明 e.exe 根本不知道 w.lib。当然,w.dll 必须在运行时出现。
    【解决方案2】:

    我认为您误解了创建存档和导入存档的作用。

    创建存档,正如您在 cmets 中正确推测的那样,创建一个包含已编译 .objs 的统一文件。现在,它可以包含您喜欢的任何代码,包括但不限于对库的动态调用。导入库是一个包含专门进行此类调用的 obj 的库,其想法是通过导入它,您的 exe 可以找到适当的符号(它们必须在您创建的可执行文件中)。

    w.lib 创建c.lib 的过程只是提取w.lib 的对象并将它们附加到c.lib 中的对象集合中。实际上,c.lib 变成了一个导入库 + 代码。

    我认为你应该这样做吗?并非如此 - 它可能会导致混淆 e.exe 依赖于什么;我认为你应该明确地让它可见而不是试图隐藏它。也就是说,这只是一个建议,而不是规则。

    【讨论】:

    • 感谢您的全面回答。我最初的假设是错误的——我认为 exe 最好不要知道 lib 的依赖关系,但现在当我从 import library + code 的角度来看它时,让 exe 知道什么是有意义的它的代码(实际上包括来自静态库的代码)取决于。
    • 我对这个答案感到困惑。在库之上构建库不是很常见吗?任何扩展库都将被视为“导入库 + 代码”。我认为隐藏正在构建的库的细节是更好的做法。
    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 2017-04-08
    • 1970-01-01
    • 2019-10-13
    • 2010-10-22
    相关资源
    最近更新 更多