我的iPhone应用程序没有链接到iPhone模拟器,我有一些问题。它告诉我有一些未定义的符号:
Undefined symbols for architecture i386:
".objc_class_name_NSRunLoop", referenced from:
pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
".objc_class_name_NSDate", referenced from:
pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
".objc_class_name_NSAutoreleasePool", referenced from:
pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
pointer-to-literal-objc-class-name in libRenderSystem_GLES2Static.a(OgreEAGL2Window.mm.o)
".objc_class_name_UIApplication", referenced from:
pointer-to-literal-objc-class-name in SampleBrowser.cpp.o
pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
".objc_class_name_NSObject", referenced from:
.objc_class_name_AppDelegate in SampleBrowser.cpp.o
".objc_class_name_UIView", referenced from:
.objc_class_name_SampleBrowserGestureView in SampleBrowser.cpp.o
.objc_class_name_InputDelegate in libOIS.a(iPhoneInputManager.mm.o)
.objc_class_name_EAGL2View in libRenderSystem_GLES2Static.a(OgreEAGL2View.mm.o)
".objc_class_name_UIScreen", referenced from:
pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
pointer-to-literal-objc-class-name in libRenderSystem_GLES2Static.a(OgreEAGL2Support.mm.o)
".objc_class_name_UIAccelerometer", referenced from:
pointer-to-literal-objc-class-name in libOIS.a(iPhoneInputManager.mm.o)
pointer-to-literal-objc-class-name in libOIS.a(iPhoneAccelerometer.mm.o)
但是这些看起来像我所链接的框架中的Objective类的名称。我想做一些研究,所以我使用nm来查看我所链接的框架的符号列表。例如
josh$ nm /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks/Foundation.framework/Foundation -arch i386 -g | grep objc_class
001a4500 S $ld$add$os10.4$.objc_class_name_NSArray
001a4501 S $ld$add$os10.4$.objc_class_name_NSCalendar
001a4502 S $ld$add$os10.4$.objc_class_name_NSData
001a4503 S $ld$add$os10.4$.objc_class_name_NSDate
001a4504 S $ld$add$os10.4$.objc_class_name_NSDateComponents
001a4505 S $ld$add$os10.4$.objc_class_name_NSDictionary
001a4506 S $ld$add$os10.4$.objc_class_name_NSEnumerator
001a4507 S $ld$add$os10.4$.objc_class_name_NSException
001a4508 S $ld$add$os10.4$.objc_class_name_NSInputStream
001a4509 S $ld$add$os10.4$.objc_class_name_NSInvocation
001a450a S $ld$add$os10.4$.objc_class_name_NSLocale
001a450b S $ld$add$os10.4$.objc_class_name_NSMethodSignature
001a450c S $ld$add$os10.4$.objc_class_name_NSMutableArray
001a450d S $ld$add$os10.4$.objc_class_name_NSMutableData
001a450e S $ld$add$os10.4$.objc_class_name_NSMutableDictionary
001a450f S $ld$add$os10.4$.objc_class_name_NSMutableSet
001a4510 S $ld$add$os10.4$.objc_class_name_NSNull
001a4511 S $ld$add$os10.4$.objc_class_name_NSObject
001a4512 S $ld$add$os10.4$.objc_class_name_NSOutputStream
001a4513 S $ld$add$os10.4$.objc_class_name_NSRunLoop
001a4514 S $ld$add$os10.4$.objc_class_name_NSSet
001a4515 S $ld$add$os10.4$.objc_class_name_NSStream
001a4516 S $ld$add$os10.4$.objc_class_name_NSTimeZone
001a4517 S $ld$add$os10.4$.objc_class_name_NSTimer
001a4548 S $ld$add$os10.4$.objc_class_name_NSURL
001a4518 S $ld$add$os10.4$.objc_class_name_NSUserDefaults
001a4549 S $ld$add$os10.5$.objc_class_name_NSURL
001a454a S $ld$hide$os10.4$.objc_class_name_NSFileWrapper
001a454b S $ld$hide$os10.5$.objc_class_name_NSFileWrapper
001a454c S $ld$hide$os10.6$.objc_class_name_NSFileWrapper
现在,在我看来,这个符号列表让我觉得框架存档正在导出链接器正在寻找的类。唯一不同的是这个$ld$add$os10.4$前缀。我想知道它为什么在那里,它意味着什么,这可能是造成我问题的原因吗?
编辑:看起来这是我的问题:Link errors in Xcode when targeting iPhoneSimulator
简而言之,去掉编译器标志-=2会导致不同的符号命名。
发布于 2012-04-12 19:52:24
$ld$add$osXX.X$SYMBOL
是一个链接器指令,允许在库中重定向符号解析。该命令位于二进制文件的__DATA部分,并由ld
在链接时进行解析,以更改导出符号的可见性。OS上的链接器实际上接受了几种不同类型的命令:
$ld$hide$osXX.X$SYMBOL
将该符号添加到忽略集中。链接器将不再将该符号导出到任何与库链接的二进制文件,即使它可能具有全局可见性。
无论定义是否存在,$ld$add$osXX.X$SYMBOL
都会在链接时将该符号添加到二进制文件中。
$ld$install_name$osXX.X
将特定二进制中的符号定义重定向到另一个二进制。这用于解决OS中的一个问题,在该问题中,CoreGraphics曾经作为ApplicationServices的子框架存在。所有符号现在都被重定向到适当的框架中。
$ld$compatibility_version
强制与早期版本的链接器兼容。
在您的例子中,您遇到了基金会中的兼容性问题。OS将NSFileWrapper在AppKit中导出,直到10.7时该符号被隐藏并移到Foundation。通常,这意味着AppKit的作者将隐藏类定义的_OBJC_CLASS_$、_OBJC_METACLASS_$和_OBJC_IVAR_$部分,以使链接器在其他地方查找该符号。但是,由于您删除了-fobjc-abi-version
标志,编译器默认返回到旧的1.xABI,它只需要隐藏和查找一个可能不存在于您试图链接的二进制文件中的.objc_class_name
。
至于您未定义的符号,这是一个简单的文件扩展名问题。.cpp是c++ 专用的文件(意思是没有NSRunloop、MSMutableArray、NSObject等)。如果希望访问这些对象,请用扩展名.mm重命名违规文件,这是一个标准的objC++文件。链接QuartzCore (用于EAGL2View)和UIKit (用于UIScreen和好友以及UIAccelerometer)也是一个不错的主意。
发布于 2012-04-12 19:12:26
我不太熟悉iOS SDK,但是为什么要为“i386”编译呢?几天前,我在玩PhoneGap时遇到了类似的问题。我刚刚从我的i386项目设置中删除了“XCode”,之后在模拟器中一切看起来都很好。尽管我可能错了。
https://stackoverflow.com/questions/10134189
复制相似问题