3

Leopard が一部のシンボルを $non_lazy_ptr でマングルするのはなぜですか? さらに重要なことに、シンボルが $non_lazy_ptr でマングルされているため、未定義のシンボル エラーを修正する最良の方法は何ですか?

4

5 に答える 5

5

From: Developer Connection - 間接アドレス指定

間接アドレッシングは、あるファイルで定義されたシンボルを別のファイルから参照できるようにするコード生成手法の名前であり、参照ファイルがシンボルを定義するファイルのレイアウトを明示的に認識している必要はありません。したがって、定義ファイルは、参照ファイルとは独立して変更できます。間接アドレス指定により、ダイナミック リンカーによって変更する必要がある場所の数が最小限に抑えられるため、コードの共有が容易になり、パフォーマンスが向上します。

ファイルが別のファイルで定義されているデータを使用する場合、シンボル参照が作成されます。シンボル参照は、シンボルのインポート元のファイルと参照されるシンボルを識別します。シンボル参照には、nonlazy と lazy の 2 種類があります。

非遅延シンボル参照は、モジュールのロード時に動的リンカーによって解決 (定義にバインド) されます。非遅延シンボル参照は、基本的にシンボル ポインター (ポインター サイズのデータ​​) です。コンパイラは、データ シンボルまたは関数アドレスの非遅延シンボル参照を生成します。

遅延シンボル参照は、(ロード時ではなく) 最初に使用されるときに動的リンカーによって解決されます。参照されたシンボルへの後続の呼び出しは、シンボルの定義に直接ジャンプします。レイジー シンボル参照は、シンボル ポインターとシンボル スタブ (シンボル ポインターを直接逆参照してジャンプする少量のコード) で構成されます。コンパイラは、別のファイルで定義された関数の呼び出しを検出すると、遅延シンボル参照を生成します。

于 2008-09-17T04:23:06.650 に答える
3

人間の言葉で言えば、コンパイラは、リンクを高速化するために $non_lazy_ptr が追加されたスタブを生成します。おそらく、 _Foo$non_lazy_ptr から参照される関数 Foo が未定義であるか、またはそのようなものであることがわかります-これらは同じものではありません。シンボルが実際に宣言され、アプリをリンクしているオブジェクト ファイル/ライブラリでエクスポートされていることを確認してください。少なくともそれが私の問題でした.私の問題が他の場所にあることがわかるまで、それは奇妙なリンカの問題だとも思っていました-Googleで見つかった他のいくつかの考えられる原因があります.

于 2008-11-14T14:19:00.947 に答える
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)

これが、一般的な UNIX 構成の外部ライブラリを iPhone または iOS で使用しようとしている他の人にも役立つことを願っています。

于 2010-08-11T20:59:58.730 に答える
1

他の誰かが私が抱えていたのと同じ問題に遭遇した場合:

ヘッダーextern NSString* const someString;ファイルに がありましたが、実装ファイルに入れるのを忘れていました。なのでNSString* const someString=@"someString";

これで解決しました。

于 2010-06-17T14:05:41.157 に答える
0

ライブラリファイルの ranlib -c は問題を修正します

于 2009-06-28T20:34:49.860 に答える