В настоящее время я столкнулся с проблемой слабой связи в 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.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
Сообщение nm -m
«a.out» выглядит следующим образом:
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello
(undefined) external _SayHello (dynamically looked up)
Что ожидалось следующим образом:
(undefined) weak external _SayHello (dynamically looked up)
Однако, когда я компилирую в Ubuntu с помощью gcc (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5, он работает как положено:
weak.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 в динамическую библиотеку, она работает как положено.
dummy.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)