创建一个在运行时链接的dylib

标签 c macos dynamic-linking

我正在尝试创建一个动态库,该库旨在在运行时链接并加载到主机环境中(例如,类似于 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 上找到的所有其他动态链接问题似乎都与库的更常见排列有关,在这种情况下,正在构建库以在可执行文件运行之前链接到可执行文件,而不是相反。我发现最接近的相关问题是:

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


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

最佳答案

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

// 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,而不是生成运行时(或者,显然是链接时)错误。

关于创建一个在运行时链接的dylib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19941730/

相关文章:

linux - 无法在 linux 中复制共享库的软链接(soft link)及其原始大小

c - 为什么我无法在控制台窗口中创建按钮?

C++。将 .dll 文件链接到项目

c++ - 使用标准库中的代码停止在 Turbo C++ 中退出输出

macos - 从 Swift 命令行程序使用 NSURLSession

objective-c - 关键当量。对于 nsbutton 对于多个 nsbuttons 不能正常工作

java - 如何在 OSX 上的 Java 7 中使用 32 位 native 库

c++ - 链接 boost - 对 `boost::serialization::singleton_module::get_lock()' 的 undefined reference

c - 在 Cygwin 中使用 NCurses 扫描 USB 设备的输入

c - 我应该禁用 C 编译器签名/未签名不匹配警告吗?