设置
假设我用 C/C++ 编写了一个程序并希望允许加载插件。典型的解决方案是将插件编写为:
plugin.c
int my_plugin_fn() {
return 7;
}
并使用类似 gcc -fpic -shared -o plugin.so plugin.c
的东西编译它然后,在加载这个插件的主程序中,我们可能有:
loader.c
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *plugin_handle = dlopen("./plugin.so", RTLD_LAZY);
if (!plugin_handle) {
printf("Could not open shared object: %s\n", dlerror());
return -1;
}
int (*fn)() = dlsym(plugin_handle, "my_plugin_fn");
char *err = dlerror();
if (err) {
printf("Could not resolve symbol: %s\n", err);
return -1;
}
printf("Plugin object returned: %d\n", fn());
return 0;
}
我用 gcc -o loader loader.c -ldl
编译了 loader.c ,运行后输出为 Plugin object returned: 7
,正如预期的那样。题
假设我们想在我们的主程序(loader.c)中添加插件可以使用的函数。例如,
loader_v2.c
#include <stdio.h>
#include <dlfcn.h>
int times_2(int x) {
return 2*x;
}
int main() {
void *plugin_handle = dlopen("./plugin_v2.so", RTLD_LAZY);
if (!plugin_handle) {
printf("Could not open shared object: %s\n", dlerror());
return -1;
}
int (*fn)() = dlsym(plugin_handle, "my_plugin_fn");
char *err = dlerror();
if (err) {
printf("Could not resolve symbol: %s\n", err);
return -1;
}
printf("Plugin object returned: %d\n", fn());
return 0;
}
plugin_v2.c extern int times_2(int);
int my_plugin_fn() {
return times_2(7);
}
以与之前相同的方式编译和运行这些文件会产生 Could not open shared object: ./loader_v2: symbol lookup error: ./plugin_v2.so: undefined symbol: times_2
.有没有办法使用
dlopen()
加载插件从加载它们的程序调用函数?
最佳答案
Is there a way to have plugins loaded using dlopen() call functions from the program that loaded them?
是的,但是您要从主可执行文件调用的函数必须从中导出,默认情况下不会发生这种情况。您可以使用
nm -D loader
查看从主二进制文件中导出的符号。 .您可以通过将主可执行文件与
-rdynamic
链接来导出主可执行文件中定义的所有函数。旗帜。一些链接器,尤其是较新版本的 GNU-ld、GOLD 和 LLD,支持
--export-dynamic-symbol
标志,它允许有选择地仅导出您需要的符号。在您的情况下,您可以链接您的
loader
可执行文件 -Wl,--export-dynamic-symbol=times_2
.
关于c++ - 从 dlopen 加载的函数可以从加载它的可执行文件中调用函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63258289/