Delphi Tokyo iOS下声明不存在函数的外部过程无编译错误,是Bug吗?
你遇到的这个情况其实是Delphi结合iOS平台链接器的正常设计,不是Bug,背后的原因可以拆解成这几点:
链接器的延迟绑定机制
Delphi在iOS平台依赖Apple的Clang链接器(ld64),对于external声明的外部符号,默认采用延迟绑定策略——简单说就是编译和链接阶段不会去验证这个符号到底在不在目标库里,只有当程序运行时第一次调用这个函数的时候,才会去查找符号是否存在。所以哪怕你写的TheHeadOfToto是个不存在的名字,编译环节也不会报错。强制加载库的逻辑生效了
你声明这个存根过程的核心需求是让链接器把libclang_rt.ios.a打包进最终的二进制里,这点其实已经实现了。因为只要你的代码里有引用这个库的external声明(不管符号是否真实存在),链接器就会把指定的库纳入处理范围,完成你想要的“强制加载”效果。Delphi编译器不做符号预检查
Delphi的编译器本身不会去解析外部静态库的符号表,它只负责生成符合调用规范的存根代码,把符号验证的工作完全交给了平台链接器。而iOS的链接器默认不会对未被调用的外部符号做严格校验,只有当你开启特定选项(比如-undefined error)时,才会在链接阶段强制检查所有符号的存在性。如何在编译阶段检查符号存在性
如果你想提前确认符号是否存在,可以用iOS SDK自带的nm工具手动查看库的符号表:nm /usr/lib/clang/lib/darwin/libclang_rt.ios.a | grep TheHeadOfToto如果没有任何输出,就说明这个符号确实不存在。另外,你也可以给Delphi项目添加自定义链接器参数
-undefined error,强制链接器在编译阶段就检查所有外部符号的有效性,这样如果符号不存在,链接时就会直接报错。
总结一下:你的操作确实达到了强制加载库的预期,而编译不报错是链接器延迟绑定的正常表现,不是Bug。如果需要编译时的符号检查,调整链接器选项就能实现。
内容的提问来源于stack exchange,提问作者zeus

