Setup
Suppose I wrote a program in C/C++ and wanted to allow plugin loading. The typical solution would be to write the plugin as:
plugin.c
int my_plugin_fn() {
return 7;
}
And compile it using something like gcc -fpic -shared -o plugin.so plugin.c
Then, in the main program that loads this plugin, we might have:
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;
}
I compiled loader.c with gcc -o loader loader.c -ldl
, and after running it, the output was Plugin object returned: 7
, as expected.
Question
Suppose we want to add functions in our main program (loader.c) that plugins can use. For example,
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);
}
Compiling and running these files in the same way as before produces Could not open shared object: ./loader_v2: symbol lookup error: ./plugin_v2.so: undefined symbol: times_2
.
Is there a way to have plugins loaded using dlopen()
call functions from the program that loaded them?