c - 如何使弱链接与 GCC 一起工作?

标签 c gcc linker weak

似乎有 3 种方法告诉 GCC 弱链接一个符号:

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

这些都不适合我:

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

我总是收到这样的链接错误:

Undefined symbols:
  "_asdf", referenced from:
      _asdf$non_lazy_ptr in ccFA05kN.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

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

最佳答案

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

使用 weak_import 的弱链接实际上只适用于动态库。您可以让它与静态链接一起工作(通过按照上面的建议指定 -undefined dynamic_lookup )但这不是一个热门的想法。这意味着在运行时之前不会检测到 undefined symbol 。这是我个人会在生产代码中避免的事情。

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

这是f.c

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);
}

从f.c创建一个动态库:

$ 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

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

$ whatnof
what, no f?

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

关于c - 如何使弱链接与 GCC 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/274753/

相关文章:

gcc - 使用 GCC 内联 ARM asm 跳转到地址

c - 关于 C 中的静态和共享库链接

c - atmega16 串行通信不工作(uart_send 和 uart_receive)

java - 把安卓手机变成 handle ,通过wifi连接电脑

c - GCC 没有重新排序堆栈变量

c++ - 为什么我会得到具有相同链接行的 undefined reference ?

c++ - 如何在 C/C++ 中链接两个 .so

c - 如何在结构中打印变量?

c - gdb - 检测到 SIGSEGV 但无法确定哪个函数和哪一行

gcc - 如果编译失败,则执行命令