You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Free Pascal生成的dylib符号可被nm查看却无法被dlsym定位

问题

在Apple Silicon架构的macOS系统上,使用Free Pascal 3.2.2编译生成.dylib动态库时遇到异常:

  • 动态库在Windows环境下可正常调用导出函数
  • macOS中用nm命令能看到符号表中的导出符号,但通过dlsym无法查找成功
  • 库可以正常加载,但dlsym返回NULL,报错"symbol not found"

相关代码与输出

  1. Free Pascal导出代码:
exports
  GetName name 'GetName',
  GetBid name 'GetBid',
  GetCard name 'GetCard';
  1. nm命令查看符号表结果:
$ nm -gU libplayer.dylib
0000000000005360 T GetBid
0000000000005370 T GetCard  
0000000000005350 T GetName
  1. C语言调用代码:
void* handle = dlopen("./libplayer.dylib", RTLD_LAZY);  // 加载成功
void* symbol = dlsym(handle, "GetName");                // 返回NULL
printf("Error: %s\n", dlerror());                      // 输出"symbol not found"
  1. 编译参数:-fPIC -k-no_order_inits -k-dylib

原因分析

macOS动态链接器对符号可见性有严格限制,Free Pascal默认编译逻辑下,即使通过exports声明符号,也可能未将其标记为全局可见属性。另外Apple Silicon架构的Mach-O格式符号导出规则和Windows PE格式不同,Windows上的导出方式无法直接适配macOS环境——nm能显示符号仅代表符号存在于表中,但不代表它对外暴露可被dlsym访问。


解决方法

方法1:添加链接器参数强制导出符号

编译时添加链接器参数,通过符号列表文件指定需要对外导出的符号:

  1. 创建一个文本文件symbols.txt,列出带下划线前缀的符号(Free Pascal在macOS下会自动给符号加下划线):
_GetName
_GetBid
_GetCard
  1. 修改编译命令,加入导出符号列表的参数:
fpc -fPIC -k-no_order_inits -k-dylib -k"-exported_symbols_list symbols.txt" yourlibrary.pas

方法2:使用编译指令强制导出所有符号

在Pascal代码开头添加{$EXPORTALL ON}指令,强制导出所有符号(适合测试场景,正式环境不推荐,会增大库体积):

{$EXPORTALL ON}
exports
  GetName name 'GetName',
  GetBid name 'GetBid',
  GetCard name 'GetCard';

方法3:验证符号可见性

用otool命令检查符号的实际属性,确认是否为对外可见:

otool -lv libplayer.dylib | grep -A 5 -B 5 GetName

如果输出中type字段为non-external,说明符号未对外导出,需要调整编译参数使其变为external。


内容的提问来源于stack exchange,提问作者Bilko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:15:57