Imagine that you have an application with a plugin based architecture, where each plugin is a *.so file that is dynamically loaded with dlopen().
The main application can refer to symbols via dlsym(), and so it may call functions of the plugin. How can the plugin call functions of the main application?
I know that the main application could provide a struct full of function pointers, which the plugin could use to call into the application. Is there any easier way than that?
Edit: here's a minimal working example to show what I mean:
app.h:
#ifndef APP_H
#define APP_H
void app_utility(void);
#endif
app.c:
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include "app.h"
void app_utility(void)
{
printf("app_utility()\n");
}
int main(int argc, char **argv)
{
void *handle;
void (*plugin_function)(void);
if (argc < 2) {
fprintf(stderr, "usage: ./app plugin.so\n");
exit(1);
}
handle = dlopen(argv[1], RTLD_NOW | RTLD_LOCAL);
if (!handle) {
fprintf(stderr, "error loading plugin: %s\n", dlerror());
exit(1);
}
plugin_function = dlsym(handle, "doit");
if (!plugin_function) {
fprintf(stderr, "error loading symbol: %s\n", dlerror());
dlclose(handle);
exit(1);
}
plugin_function();
dlclose(handle);
return 0;
}
plugin.c:
#include <stdio.h>
#include "app.h"
void doit(void)
{
printf("doit()\n");
app_utility();
printf("did it!\n");
}
Example usage:
$ gcc -o app app.c -ldl
$ gcc -shared -o plugin.so
$ ./app ./plugin.so
error loading plugin: ./plugin.so: undefined symbol: app_utility
There is a option you can pass to gcc when you invoke it to create the executable for the main application:
-rdynamicThe GCC documentation for
-rdynamic:The
ldmanual page for--export-dynamicincludes this paragraph: