我们有一个系统在很大程度上依赖使用dlopen()加载模块。我们的模块是自描述的,带有一个符号,指向与加载模块相关的一些元数据(描述,加载顺序,加载标志等)。如何获取函数地址时的RTLD_LAZY行为?
我们首先加载指定RTLD_LAZY
标志模块dlopen的(),让我们从元数据的需要,然后加载模块,真正以后(在我们知道的加载顺序应该是什么,他们如何应加载等)。
这一段时间工作得很好,但我们最近发现,获取函数地址需要在加载时解析函数。我们可以通过哪些方法解决此问题?
我已经把一个相当小的例子演示了这个问题。
/* foo.h */
void foo(void);
/* foo.c */
void foo(void) {}
/* bar.c */
#include "foo.h"
/* Calls foo normally */
void bar(void) { foo(); }
/* bam.c */
#include "foo.h"
static void (*f)(void);
/* Takes the address of foo */
void bam(void) { f = foo; }
/* rtld_lazy.c */
#include <dlfcn.h>
#include <stdio.h>
void check(const char *module) {
void *mod = dlopen(module, RTLD_LAZY);
if (mod) {
printf("%s successfully loaded\n", module);
dlclose(mod);
} else {
printf("%s failed to load: %s\n", module, dlerror());
}
}
int main() {
check("./bar.so");
check("./bam.so");
check("./foo.so");
}
用下面的输出:
./bar.so successfully loaded
./bam.so failed to load: ./bam.so: undefined symbol: foo
./foo.so successfully loaded
这是个好主意。但在我们的具体情况下,这并不实际。具体来说,有一个编译器标志可以将所有内容静态链接在一起,而不是使用可加载模块。谢谢,不过。 – leedm777