如何与GCC进行弱连接工作?

似乎有3种方式告诉GCC弱连接符号:

  • __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”,引自:
       _asdf $ non_lazy_ptr在ccFA05kN.o中
 ld:找不到符号
 collect2:ld返回1退出状态 

我在OS X 10.5.5上使用GCC 4.0.1。 我究竟做错了什么?

我只是调查了一下,并认为其他人可能会对我的发现感兴趣。

与weak_import的弱连接实际上只适用于动态库。 您可以使用静态链接(通过如上所述指定-undefined dynamic_lookup),但这不是一个好主意。 这意味着在运行时之前不会检测到任何未定义的符号。 我个人会在生产代码中避免这种情况。

这是一个Mac OS X终端会话,展示了如何使其工作:

这是fc

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

这是什么

 #include  #include  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 fc 

编译并链接动态库,列出动态库。

 $ 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 

运行相同的whatnof看看会发生什么:

 $ whatnof what, no f? 

weak_import的基本思想(或“用例”)是它允许您链接一组动态(共享)库,但是然后针对相同库的早期版本运行相同的代码。 您可以检查函数是否为NULL,以查看它们是否在代码当前运行的特定动态库中受支持。 这似乎是Xcode支持的基本开发模型的一部分。 我希望这个例子很有用; 它帮助我放松了对Xcode设计的这一部分。

-Wl,-flat_namespace,-undefined,dynamic_lookup添加到用于执行最终链接的gcc编译器行。

您需要将MACOSX_DEPLOYMENT_TARGET变量设置为10.2或更高版本。 请参阅Apple的文档及其关于弱链接的技术说明。

从gcc doc手册:

weak属性导致声明作为弱符号而不是全局符号发出。 这主要用于定义可以在用户代码中重写的库函数,尽管它也可以与非函数声明一起使用。 ELF目标支持弱符号,并且在使用GNU汇编器和链接器时也支持a.out目标。

这意味着对象合法化以覆盖弱符号(在另一个对象/库中定义)而不会在链接时获得错误。 不清楚的是你是否用符号链接库。 似乎您没有定义符号,并且库没有正确链接。