MacOS下如何让Xcode中框架与程序共享一份动态库内存实例
解决MacOS下动态库重复加载的问题
MacOS的动态链接器dyld会根据动态库的**安装路径(Install Name)**和文件唯一标识判断是否加载同一个库副本。你遇到的重复加载问题,核心是Engine和Game对.dylib的路径配置不一致,导致dyld判定为两个不同库。以下是具体解决步骤:
1. 统一动态库的Install Name配置
打开自定义.dylib的Xcode目标,在Build Settings中修改两项:
Installation Directory:设置为@rpathDynamic Library Install Name:设置为@rpath/YourLibName.dylib(替换为你的.dylib实际文件名)
这样所有依赖该库的模块(Engine和Game)都会通过rpath机制定位同一个库文件。
2. 调整Engine框架的链接与嵌入规则
Engine框架只需链接.dylib,无需单独嵌入(避免重复打包):
- 在Engine的Build Phases中,将.dylib添加到
Link Binary With Libraries列表,确保链接正常 - 不要将.dylib添加到
Embed Frameworks中 - 在Engine的Build Settings里,添加
Runpath Search Paths为@executable_path/../Frameworks(该路径指向最终Game包的Frameworks目录)
3. 配置Game目标的嵌入与路径
仅在Game目标中嵌入一份.dylib:
- 在Game的Build Phases中,将.dylib添加到
Embed Frameworks列表,确保它被复制到Game.app/Contents/Frameworks目录下 - 检查Game的Build Settings,确认
Runpath Search Paths包含@executable_path/../Frameworks(Xcode默认已添加,若缺失则手动补上)
4. 验证与清理
- 清理Xcode的Build缓存(
Product > Clean Build Folder),避免旧文件干扰 - 构建完成后,用
otool命令检查依赖路径:
两者输出中,.dylib的依赖路径应均为# 检查Game可执行文件的依赖 otool -L Game.app/Contents/MacOS/Game # 检查Engine框架的依赖 otool -L Game.app/Contents/Frameworks/Engine.framework/Engine@rpath/YourLibName.dylib,且Game.app/Contents/Frameworks下仅存在一份该.dylib文件。
完成以上配置后,dyld会只加载一次.dylib,Engine和Game调用的函数地址与内部状态将保持一致。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

