macOS12下运行.NET Tesseract应用如何正确引用libdl.dylib
macOS 12 运行依赖
libdl.so的.NET Tesseract应用报DllNotFoundException 解决方案 根因说明
libdl.so是Linux平台的动态加载库,macOS平台不存在独立的libdl.dylib文件。从OS X 10.5版本开始,dlopen/dlsym/dlclose等libdl相关的所有导出符号,都已经集成到系统核心库/usr/lib/libSystem.B.dylib中。- 检索到的
.tbd文件是Xcode提供给编译期链接器使用的文本格式桩文件,仅用于记录动态库的导出符号、路径等元信息,不是可被运行时动态加载器识别的Mach-O二进制格式,直接软链接为.so文件必然加载失败。 - 检索到的tvOS/watchOS/iOS模拟器路径下的
libdl.dylib是为其他苹果平台编译的二进制,架构、ABI、签名均不兼容macOS运行时,直接软链接会触发签名校验、平台不匹配错误。
可行解决方法(按推荐优先级排序)
方法1:项目内配置原生库映射(无系统侵入,最推荐)
不需要修改系统文件,仅通过.NET提供的原生库加载机制重定向映射即可,两种实现方式二选一:
- 代码级映射:在应用入口(
Program.cs最开头,所有业务逻辑执行前)添加如下DLL导入解析回调:
using System.Runtime.InteropServices; // 替换为你项目中任意一个公开类的类型即可 NativeLibrary.SetDllImportResolver(typeof(Program).Assembly, (libName, assembly, searchPath) => { if (libName == "libdl.so" && RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return NativeLibrary.Load("libSystem.B.dylib", assembly, searchPath); } return IntPtr.Zero; });
- 配置文件映射:在项目根目录新建
runtimeconfig.template.json文件,写入如下配置,编译后会自动合并到应用的运行时配置中,无需修改业务代码:
{ "runtimeOptions": { "configProperties": { "Microsoft.NETCore.DllMap": { "libdl.so": { "osx": "libSystem.B.dylib" } } } } }
方法2:系统级软链兼容(适合不想修改项目配置的场景)
注意:macOS SIP系统完整性保护会锁定/usr/lib目录,无需关闭SIP往该路径写入文件,/usr/local/lib默认在dyld动态库搜索路径列表中,软链到该路径即可被正常识别加载。
直接执行如下命令建立软链即可:
sudo ln -s /usr/lib/libSystem.B.dylib /usr/local/lib/libdl.so
执行完成后重启终端/IDE,再运行应用即可正常加载。
避坑说明
- 不要尝试下载第三方来源的
libdl.dylib文件,这类系统核心库版本不匹配极易引发崩溃、安全问题,系统自带的libSystem已经包含所有需要的符号。 - 不要软链其他平台(iOS/tvOS/WatchOS)的dylib文件,平台ABI不兼容无法在macOS上加载。
- 不要使用.tbd文件作为运行时加载目标,该格式仅服务于编译阶段链接流程。
内容的提问来源于stack exchange,提问作者jamesdlivesinatree
相关产品推荐
相关产品推荐

