2

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 -C クラスの名前のように見えます。掘り下げたいと思ったので、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$ プレフィックスです。なぜそこにあるのか、それが何を意味するのか、そしておそらくそれが私の問題を引き起こしているのでしょうか?

編集:これは私の問題だったようです: iPhoneSimulator をターゲットにするときの Xcode のリンク エラー

つまり、コンパイラ フラグ -fobjc-abi-version=2 を省略すると、異なるシンボル名が付けられます。

4

2 に答える 2

2

$ld$add$osXX.X$SYMBOLライブラリ内のシンボル解決をリダイレクトできるようにするリンカディレクティブです。このコマンドは、バイナリの__DATAセクションにあり、ldリンク時に解析されて、エクスポートされたシンボルの表示を変更します。OS Xのリンカは、実際にはこれらのコマンドのかなりの数の異なる種類を受け入れます。

$ld$hide$osXX.X$SYMBOLそのシンボルを無視セットに追加します。リンカは、グローバルに表示されている場合でも、ライブラリにリンクしているバイナリにそのシンボルをエクスポートしなくなります。

$ld$add$osXX.X$SYMBOL定義が存在するかどうかに関係なく、リンク時にそのシンボルをバイナリに追加します。

$ld$install_name$osXX.X特定のバイナリのシンボルの定義を別のバイナリにリダイレクトします。これは、CoreGraphicsがApplicationServicesのサブフレームワークとして存在していたOSXの問題を回避するために使用されます。これで、すべてのシンボルが適切なフレームワークにリダイレクトされます。

$ld$compatibility_version以前のバージョンのリンカーとの互換性を強制します。

あなたの場合、Foundationの互換性の問題にぶつかりました。OS Xは、シンボルがそこから隠されてFoundationに移動する10.7まで、AppKitでNSFileWrapperをエクスポートしました。通常、これは、AppKitの作成者がクラス定義の_OBJC_CLASS _ $、_ OBJC_METACLASS_ $、および_OBJC_IVAR_ $の部分を非表示にして、リンカーがそのシンボルを他の場所で検索できるようにすることを意味します。ただし、フラグを削除したため、コンパイラはデフォルトで古い1.x ABIに戻ります。これは、リンクしようとしているバイナリにおそらく存在しない-fobjc-abi-versionaを非表示にして見つけることだけを必要とします。.objc_class_name

未定義のシンボルに関しては、それは単純なファイル拡張子の問題です。.cppはc++のみのファイルです(つまり、NSRunloop、MSMutableArray、NSObjectなどはありません)。これらのオブジェクトにアクセスする場合は、問題のあるファイルの名前を、標準のobjC++ファイルである拡張子.mmに変更します。QuartzCore(EAGL2Viewの場合)およびUIKit(UIScreenおよびUIAccelerometerと一緒の友人の場合)に対してリンクしてインポートすることもお勧めします。

于 2012-04-13T03:52:24.813 に答える
0

iOS SDK についてはよくわかりませんが、なぜ「i386」用にコンパイルしているのですか? 数日前、PhoneGap で遊んでいるときに、このような問題に遭遇しました。XCodeプロジェクト設定から「i386」を削除したところ、その後シミュレーターですべて正常に動作するように見えました。私は間違っているかもしれませんが。

于 2012-04-13T03:12:26.240 に答える