5

私はいくつかの静的ライブラリをリンクするiOSアプリに取り組んでいます。課題は、これらのリンクされたライブラリが、異なる実装で同じメソッド名を定義することです。duplicate symbol definition奇妙なことに、エラーは発生しません。しかし、当然のことながら、私はメソッドの1つの実装にしかアクセスできなくなります。

より明確にするために、私がlibAとlibBを持っていて、両方ともfunc1()と呼ばれるグローバルCメソッドを定義しているとしましょう。

libAとlibBの両方をリンクし、func1()を呼び出すと、コンパイルの警告なしにlibAまたはlibBの実装に解決されます。ただし、libAのfunc1()とlibBのfunc1()の両方に個別にアクセスできる必要があります。

Cで(シンボルの名前変更を介して)どのように実行できるかを説明する同様のSO投稿がありobjcopyますが、残念ながら、私が知ったように、ツールはARMアーキテクチャ(したがってiPhone)では機能しません。

(App Storeに送信するため、ダイナミックリンクはオプションではありません)

4

1 に答える 1

4

運が良かったようです-ARMバイナリ形式でシンボルの名前を変更できますが、メソッドよりも少しハックobjcopyです...

注: これは最小限のテストにすぎません。これを試す前に、問題のすべてのライブラリのバックアップを作成することを強くお勧めします。

また、これは C++ コンパイラでコンパイルされていないファイルに対してのみ機能することに注意してください! これらのファイルで C++ コンパイラが使用された場合、これは失敗します。

  1. まず、適切な 16 進エディタが必要です。この例では、Hex Fiendを使用します。
  2. 次に、自分のライブラリのコピーを開きます。それlib1-renamed.aを と呼び、次の操作を行います。

    • 名前を変更したいシンボルの名前を見つけます。ツールを使用して見つけることができますnm。ヘッダー名がわかっている場合は、設定する必要があります。

    • 次に、hex fiend を使用して、古い名前 (この場合は ) をテキストで置き換えfoo、新しい名前 (この場合はbar) を付けます。これらの名前は同じ長さでなければなりません。そうしないと、バイナリのオフセットが壊れます!

      foo:の名前を含む関数が複数ある場合、問題が発生する可能性があります。

  3. barここで、変更したライブラリのヘッダーを編集して、古い関数名の代わりに新しい関数名 ( ) を使用する必要があります。

上記の 3 つの簡単な†</sup> 手順を適切に実行すると、2 つのファイルを正常にコンパイルおよびリンクし、両方の実装を呼び出すことができるはずです。

ユニバーサル バイナリ (たとえば、シミュレータでも動作するもの) でこれを実行しようとしている場合は、i386/x64 バイナリlipoを使用して 2 つのバイナリを分離し、objcopy次に私の方法を使用することをお勧めします。 ARMバイナリ、およびlipoそれを元に戻します。

†: シンプルさは保証されておらず、Richard J. Ross III スーパー保証の対象外です。スーパー保証の詳細については、今すぐ 1-800-FREE-WARRANTY までお電話ください。それが 1-800-FREE-WARRANTY です。

于 2013-03-11T19:47:31.863 に答える