为什么Leopard会使用$ non_lazy_ptr修改一些符号?更重要的是,修复未定义的符号错误的最佳方法是什么,因为符号已被$ non_lazy_ptr损坏?
答案 0 :(得分:5)
来自:Developer Connection - Indirect Addressing
间接寻址是代码生成技术的名称,它允许从另一个文件中引用在一个文件中定义的符号,而不要求引用文件明确知道定义该符号的文件的布局。因此,可以独立于引用文件修改定义文件。间接寻址最大限度地减少了动态链接器必须修改的位置数量,这有助于代码共享并提高性能。
当文件使用在另一个文件中定义的数据时,它会创建符号引用。符号引用标识从中导入符号的文件和引用的符号。有两种类型的符号引用:nonlazy和lazy。
加载模块时,动态链接器会解析非绑定符号引用(绑定到它们的定义)。 非惰性符号引用本质上是符号指针 - 指针大小的数据。编译器为数据符号或函数地址生成非语义符号引用。
动态链接器在第一次使用时(不是在加载时)解析了惰性符号引用。对引用符号的后续调用直接跳转到符号的定义。 延迟符号引用由符号指针和符号存根组成,这些代码直接解引用并跳过符号指针。编译器在遇到对另一个文件中定义的函数的调用时会生成惰性符号引用。
答案 1 :(得分:3)
在人类说话中:编译器会生成附加了$ non_lazy_ptr的存根,以加快链接速度。你可能会看到从_Foo $ non_lazy_ptr引用的函数Foo是未定义的,或类似的东西 - 这些都不是一回事。确保在您将应用程序链接到的目标文件/库中实际声明和导出符号。至少那是我的问题,我还认为这是一个奇怪的链接器事情,直到我发现我的问题在其他地方 - 在Google上发现了其他几个可能的原因。
答案 2 :(得分:2)
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配置的外部库。
答案 3 :(得分:1)
如果其他人遇到了我遇到的同样问题:
头文件中有extern NSString* const someString;
,但忘了把它作为实现文件。作为NSString* const someString=@"someString";
这解决了它。
答案 4 :(得分:0)
ranlib -c修复了问题