Skip to content

Instantly share code, notes, and snippets.

@mgdm
Last active January 1, 2016 11:19
Show Gist options
  • Select an option

  • Save mgdm/8137592 to your computer and use it in GitHub Desktop.

Select an option

Save mgdm/8137592 to your computer and use it in GitHub Desktop.
A simple and probably flawed base for a plugin system using DSOs in C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "plugin_api.h"
plugin_repository *repo;
int load_plugin(plugin_repository *repo, char *name)
{
char path[256], init_func_name[128];
size_t len;
int ret;
void *handle;
plugin *current, *new_plugin;
plugin_init_func init_func;
len = snprintf(path, 256, "%s/%s.so", PLUGIN_BASE_PATH, name);
if (len >= 256) {
fprintf(stderr, "Plugin path name overflowed\n");
return -1;
}
len = snprintf(init_func_name, 128, "init_%s", name);
if (len >= 128) {
fprintf(stderr, "Plugin func name overflowed\n");
return -1;
}
printf("Loading plugin %s from file %s\n", name, path);
new_plugin = (plugin *) calloc(1, sizeof(plugin));
if (repo->plugins == NULL) {
repo->plugins = calloc(1, sizeof(plugin));
}
current = repo->plugins;
while(current->next) {
current = repo->plugins->next;
}
new_plugin->name = strdup(name);
new_plugin->handle = dlopen(path, RTLD_NOW);
if (!new_plugin->handle) {
fprintf(stderr, "Failed to load plugin %s - object %s not found\n", name, path);
free(new_plugin);
return -1;
}
init_func = (plugin_init_func) (intptr_t) dlsym(new_plugin->handle, init_func_name);
if (!init_func) {
fprintf(stderr, "Failed to find plugin init function %s in %s\n", init_func_name, path);
free(new_plugin);
return -1;
}
ret = init_func(repo);
if (ret < 0) {
fprintf(stderr, "Failed to initialize plugin %s - function %s returned %d\n", name, init_func_name, ret);
return -1;
}
current->next = new_plugin;
fprintf(stderr, "Loaded plugin %s", name);
return 0;
}
int main(int argc, char **argv)
{
int i;
repo = (plugin_repository *) calloc(1, sizeof(plugin_repository));
for (i = 1; i < argc; i++)
{
load_plugin(repo, argv[i]);
}
return 0;
}
all:
gcc -g -o plugin main.c
gcc -o test.so -g -fPIC -shared test.c
#define PLUGIN_BASE_PATH "/Users/michael/Code/plugins"
typedef struct _plugin plugin;
struct _plugin
{
char *name;
void *handle;
plugin *next;
};
typedef struct _plugin_repository
{
plugin *plugins;
} plugin_repository;
typedef int (*plugin_init_func)(plugin_repository *);
#include <stdio.h>
#include "plugin_api.h"
int init_test(plugin_repository *repo)
{
printf("Hello from inside the test plugin\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment