几何尺寸与公差论坛

 找回密码
 注册
查看: 131|回复: 7

如何将多个静态库合成一个动态库?

  [复制链接]
发表于 2024-11-4 16:13:00 | 显示全部楼层 |阅读模式
当动态库B引用了静态库A,静态库A引用了静态库C,如何设置solution的exe编译和调试仅仅调用B,而不用拷贝A和C到exe路径下?
 楼主| 发表于 2024-11-4 16:14:06 | 显示全部楼层
要实现仅将动态库 B.dll(依赖静态库 A.lib 和 C.lib)放置在 exe 路径下,并且在运行时无需拷贝 A 和 C,可以按照以下步骤操作,以确保 A.lib 和 C.lib 中的符号完全包含在 B.dll 中。这会让 exe 只需要依赖 B.dll,而不必额外依赖 A 和 C。
实现方案

当 A.lib 和 C.lib 是静态库时,目标是将这两个库的代码完全包含在 B.dll 中。只要 B.dll 中包含了 A.lib 和 C.lib 的全部符号,最终生成的 exe 只需要 B.dll 就可以运行,无需 A 和 C。
解决步骤
1. 在动态库 B.dll 中链接静态库 A.lib 和 C.lib

确保在 B.dll 的项目设置中,将 A.lib 和 C.lib 作为依赖项进行链接。这会将 A 和 C 的所有符号合并到 B.dll 中。

在 Visual Studio 中,可以按照以下步骤设置:

    打开 B 项目的属性。
    选择 配置属性 -> 链接器 -> 输入 -> 附加依赖项。
    在附加依赖项中添加 A.lib 和 C.lib,确保 B 项目在构建时会链接 A 和 C 的符号。

2. 使用 /WHOLEARCHIVE 选项强制包含所有符号

在链接 A.lib 和 C.lib 时,编译器可能会优化掉未使用的符号(即“裁剪”)。为了确保 A 和 C 的所有符号都包含在 B.dll 中,可以使用 /WHOLEARCHIVE 选项。

在 Visual Studio 中使用 /WHOLEARCHIVE 的方法:

    右键点击 B 项目 -> 属性。

    选择 配置属性 -> 链接器 -> 命令行。

    在 附加选项 中添加以下命令:
 楼主| 发表于 2024-11-4 16:14:24 | 显示全部楼层
/WHOLEARCHIVE:A.lib /WHOLEARCHIVE:C.lib
 楼主| 发表于 2024-11-4 16:14:50 | 显示全部楼层
这会确保静态库 A 和 C 的所有符号都包含在 B.dll 中,而不会被裁剪掉。
3. 设置头文件中的导出符号(可选)

如果 A 和 C 中的某些符号需要在 B.dll 中对外导出,则需要在头文件中使用 __declspec(dllexport)。通常,您可以在 B 项目中的头文件里添加导出宏:
 楼主| 发表于 2024-11-4 16:15:01 | 显示全部楼层
#ifdef B_EXPORTS
#define B_API __declspec(dllexport)
#else
#define B_API __declspec(dllimport)
#endif
 楼主| 发表于 2024-11-4 16:15:13 | 显示全部楼层
然后在声明需要导出的函数或类时使用 B_API,例如:
 楼主| 发表于 2024-11-4 16:15:20 | 显示全部楼层
// 假设这是 A 库或 C 库中的一个函数声明
B_API void FunctionFromAorC();
 楼主| 发表于 2024-11-4 16:16:13 | 显示全部楼层
这样会确保 A 和 C 中的符号在 B.dll 中可以被外部代码访问。
4. 编译 B.dll 并验证

完成以上设置后,重新编译 B.dll。如果配置正确,生成的 B.dll 应该包含 A 和 C 的所有符号。

可以使用 F:\tool\dllexp.exe 工具来检查 B.dll 中是否包含了 A 和 C 的符号。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-12-21 23:54 , Processed in 0.039927 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表