28

シンボルを弱リンクするように GCC に指示する方法は 3 つあります。

  • __attribute__((weak_import))
  • __attribute__((weak))
  • #pragma weak symbol_name

これらのどれも私にとってはうまくいきません:

#pragma weak asdf
extern void asdf(void) __attribute__((weak_import, weak));
...
{
    if(asdf != NULL) asdf();
}

私はいつも次のようなリンクエラーを受け取ります:

未定義のシンボル:
  「_asdf」、次から参照:
      ccFA05kN.o の _asdf$non_lazy_ptr
ld: シンボルが見つかりません
collect2: ld が 1 つの終了ステータスを返しました

OS X 10.5.5 で GCC 4.0.1 を使用しています。私は何を間違っていますか?

4

5 に答える 5

34

これを調べたところ、他の人が私の調査結果に興味を持っているのではないかと思いました。

weak_import を使用した弱いリンクは、実際には動的ライブラリでのみうまく機能します。静的リンクで動作させることができます (上記のように -undefined dynamic_lookup を指定することにより) が、これはそれほどホットなアイデアではありません。これは、実行時まで未定義のシンボルが検出されないことを意味します。これは、個人的には製品コードでは避けたいことです。

これを機能させる方法を示す Mac OS X ターミナル セッションを次に示します。

FCはこちら

int f(int n)
{
    return n * 7;
}

ここにwhatnof.cがあります

#include <stdio.h>
#include <stdlib.h>

extern int f (int) __attribute__((weak_import));

int main() {
    if(f == NULL)
        printf("what, no f?\n");
    else
        printf("f(8) is %d\n", f(8));
    exit(0);
}

fc から動的ライブラリを作成します。

$ cc -dynamiclib -o f.dylib f.c

動的ライブラリに対してコンパイルおよびリンクし、動的ライブラリを一覧表示します。

$ cc -o whatnof whatnof.c f.dylib
$ otool -L whatnof
whatnof:
       f.dylib (compatibility version 0.0.0, current version 0.0.0)
       /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

whatnof を実行して、何が起こるかを確認します。

$ whatnof
f(8) is 56

f.dylib を空のライブラリ (シンボルなし) に置き換えます。

$ mv f.dylib f.dylib.real
$ touch null.c
$ cc -dynamiclib -o f.dylib null.c

同じ whatnoof を実行して、何が起こるかを確認します。

$ whatnof
what, no f?

weak_import の基本的な考え方 (または「ユースケース」) は、一連の動的 (共有) ライブラリに対してリンクできるが、同じライブラリの以前のバージョンに対して同じコードを実行できるというものです。NULL に対して関数をチェックして、コードが現在実行されている特定の動的ライブラリで関数がサポートされているかどうかを確認できます。これは、Xcode がサポートする基本的な開発モデルの一部のようです。この例がお役に立てば幸いです。これは、Xcode 設計のこの部分について私の心を落ち着かせるのに役立ちました。

于 2010-09-20T08:34:27.077 に答える
7

-Wl,-flat_namespace,-undefined,dynamic_lookup最終的なリンクを行うために使用する gcc コンパイラ行に追加します。

于 2009-04-08T14:27:19.123 に答える
4

MACOSX_DEPLOYMENT_TARGET 変数を 10.2 以降に設定する必要があります。弱いリンクに関するApple のドキュメント技術情報を参照してください。

于 2008-11-08T15:32:51.150 に答える
1

gcc docマニュアルから:

弱い

weak属性を使用すると、宣言はグローバルではなく弱いシンボルとして発行されます。これは主に、ユーザーコードでオーバーライドできるライブラリ関数を定義する場合に役立ちますが、関数以外の宣言でも使用できます。弱いシンボルは、ELFターゲット、およびGNUアセンブラとリンカーを使用する場合のa.outターゲットでサポートされます。

これは、リンク時にエラーが発生することなく、オブジェクトが弱いシンボル(別のオブジェクト/ライブラリで定義されている)を上書きすることを正当化することを意味します。不明確なのは、ライブラリを弱い記号でリンクしているかどうかです。シンボルを定義しておらず、ライブラリが適切にリンクされていないようです。

于 2008-11-08T15:05:39.473 に答える