11

現在、Mac OS X 10.6.7 と Xcode 4.0.2 で弱いリンクの問題に遭遇しました。

robin@chameleon:/tmp/o$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

ドキュメントhttp://developer.apple.com/library/mac/#technotes/tn2064/_index.htmlにあるように、弱いリンク シンボルに gcc属性((weak_import)) を使用できます。ただし、次のサンプル コードは常にコンパイル エラーをスローします。次のように:

弱い.c :

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

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

エラーメッセージは次のとおりです。

robin@chameleon:/tmp/o$ gcc weak.c 
Undefined symbols for architecture x86_64:
  "_f", referenced from:
      _main in cceOf2wN.o
     (maybe you meant: __dyld_func_lookup)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

オプション-undefined dynamic_lookupを使用しても、実行時にエラーがスローされます。

robin@chameleon:/tmp/o$ gcc -undefined dynamic_lookup weak.c 
robin@chameleon:/tmp/o$ ./a.out 
dyld: Symbol not found: _SayHello
  Referenced from: /private/tmp/o/./a.out
  Expected in: dynamic lookup

Trace/BPT trap

「a.out」のnm -mメッセージは次のとおりです。

robin@chameleon:/tmp/o$ nm -m a.out  | grep Hello

(undefined) external _SayHello (dynamically looked up)

これは次のように予想されました:

(undefined) weak external _SayHello (dynamically looked up)

ただし、gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 を使用して Ubuntu でコンパイルすると、期待どおりに動作します。

弱い.c :

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

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

  robin@robinz:/tmp/o$ gcc weak.c robin@robinz:/tmp/o$ ./a.out SayHello が存在しません!

バイナリでの SayHello のシンボルは次のとおりです。

robin@robinz:/tmp/o$ nm a.out | grep Hello
w SayHello

"w" シンボルは、特に弱いオブジェクト シンボルとしてタグ付けされていない弱いシンボルです。

古い xcode 3.2 をテストすると、期待どおりに動作します。

誰かがこれについて私を助けることができますか? ldのバグでしたか?

そして、さらに興味深いものを見つけました。動的ライブラリで SayHello シンボルをエクスポートするダミー ライブラリを作成すると、期待どおりに動作します。

ダミー.c :

int SayHello() {
    return;
}

 

robin@chameleon:/tmp/o$ gcc -dynamiclib -o libdummy.dylib dummy.c 
robin@chameleon:/tmp/o$ gcc weak.c libdummy.dylib 
robin@chameleon:/tmp/o$ ./a.out 
SayHello is present!

「libdummy.dylib」が存在しない場合:

robin@chameleon:/tmp/o$ rm libdummy.dylib 
robin@chameleon:/tmp/o$ ./a.out 
SayHello is not present!

期待どおりに動作します!予想どおり、nm メッセージにウィーク シンボルが表示されるようになりました。

robin@chameleon:/tmp/o$ nm -m a.out | grep Hello

                 (undefined) weak external _SayHello (from libdummy)
4

0 に答える 0