使用$ non_lazy_ptr处理OSX 10.5豹纹符号
为什么Leopard用$ non_lazy_ptr破坏某些符号?更重要的是,由于符号已被$ non_lazy_ptr破坏,因此修复未定义符号错误的最佳方法是什么?
解决方案
回答
来自:开发人员连接间接寻址
间接寻址是代码生成技术的名称,该技术允许从一个文件中引用一个文件中定义的符号,而无需引用文件对定义该符号的文件的布局有明确的了解。因此,可以独立于引用文件来修改定义文件。间接寻址可最大程度地减少必须由动态链接程序修改的位置数量,从而促进代码共享并提高性能。
当一个文件使用另一个文件中定义的数据时,它将创建符号引用。符号引用标识从中导入符号的文件和引用的符号。符号引用有两种类型:nonlazy和lazy。
加载模块时,动态链接程序会解析(绑定到其定义)非延迟符号引用。
非惰性符号引用实质上是符号指针,即指针大小的数据。编译器为数据符号或者函数地址生成非惰性符号引用。
动态链接器在首次使用时会解析惰性符号引用(而不是在加载时)。对引用符号的后续调用将直接跳至符号定义。
惰性符号引用由符号指针和符号存根组成,少量的代码直接取消引用并跳过符号指针。当编译器遇到对另一个文件中定义的函数的调用时,它会生成惰性符号引用。
回答
用人类的话来说:编译器生成带有$ non_lazy_ptr的存根,以加快链接速度。我们可能会看到从_Foo $ non_lazy_ptr引用的函数Foo是未定义的,或者类似的东西不是同一回事。确保在链接应用程序的目标文件/库中确实声明并导出了该符号。至少那是我的问题,在我发现问题出在其他地方之前,我还认为这是一个奇怪的链接器,在Google上还有其他可能的原因。
回答
库文件上的ranlib -c解决了该问题
回答
如果有人偶然发现了我遇到的相同问题:
在头文件中有一个extern NSString * const someString;
,但是忘了把它放在实现文件中了。为NSString * const someString = @" someString";
这解决了。
回答
ranlib -c libwhatever.a
是解决该问题的可靠方法。在为iOS构建PJSIP库时,我遇到了同样的问题。该库排序使用基于autoconf的make系统,但需要对各种文件进行一些调整以使所有内容都适用于iOS。在执行此操作的过程中,我设法删除了库规则中的ranlib行,然后开始在我的项目链接中收到有关未定义的_PJ_NO_MEMORY_EXCEPTION $ _PJ_NO_MEMORY_EXCEPTION $ non_lazy_ptr中的错误
将ranlib行添加回库文件即可解决该问题。现在,我在rules.mak中完整输入LIBS是
$(LIB): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP) if test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi $(LIBTOOL) -o $(LIB) $(OBJS) $(RANLIB) -c $(LIB)
希望这也会对其他人有所帮助,并尝试在iPhone或者iOS上使用由UNIX配置的常规外部库。