1

我正在尝试创建一个动态库,该库旨在在运行时链接并加载到主机环境中(例如,类似于 Java 中类加载的工作方式)。因此,我希望动态库留下一些“悬空”引用,我希望它在加载到该环境时从其宿主环境中获取。

我的问题是,如果不将动态库显式链接到现有符号,我无法弄清楚如何创建动态库。我希望生成一个不依赖于特定主机可执行文件(或主机库)的动态库,而是一个能够dlopen在任何主机中加载(例如通过)的动态库,只要主机使几个符号可供使用.

现在,我尝试过的任何链接命令都会导致抱怨缺少符号。我希望它允许缺少符号(理想情况下,只是特别指定的符号)。

例如,以下是 OS X 上的错误记录:

$ cat frotz.c 
void blort(void);

void run(void) {
    blort();
}

$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
  "_blort", referenced from:
      _run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果我使用 GNU 工具链(在 Linux 上)做同样的事情,它会告诉我:

$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC

事实上,添加-fPIC到 C 编译命令似乎可以解决该环境中的问题。但是,它似乎在 OS X 中没有任何影响。

我可以在 SO 上找到的所有其他动态链接问题似乎都是关于更常见的库安排,其中正在构建一个库以在该可执行文件运行之前链接到该可执行文件,而不是相反。我发现的最接近的相关问题是:

不幸的是,它的信息很少,与我在这里提出的问题无关。


更新:我从答案中提取了信息以及我想出的所有其他信息,并将这个例子放在一起:

4

1 回答 1

1

据我所知,您想使用弱链接:

// mark function as weakly-linked
extern void foo() __attribute__((weak));

// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup

如果一个弱函数可以在运行时被解析,那么它将被解析。如果不能,它将是NULL,而不是生成运行时(或者,显然是链接时)错误。

于 2013-11-12T23:14:13.133 回答