plugin.h


			
/* plugin.h - Interface to the plugin subsystem */


/* definition of the exported methods */
struct hfp_methods {
	int (*hello) (void);
	int (*bye) (void);
};

test.c


			
/* test.c - just a simple plugin */

/*
 * to compile: gcc test.c -o test.so -shared -fPIC
 */
#include 
#include 

#include "plugin.h"

struct hfp_methods methods;

int hello_world(void)
{
	printf("Hello (plugin) world!\n");
	return 0;
}

int bye_world(void)
{
	printf("Good-bye (cruel) world!\n");
	return 0;
}

struct hfp_methods *hfp_plugin_init(void)
{
	methods.hello = &hello_world;
	methods.bye = &bye_world;

	return &methods;
}

loader.c


			
/* loader.c - just a simple plugin loader */

/*
 * to compile: gcc -rdynamic loader.c -o loader -ldl
 * to use: ./loader
 */

#include 
#include 
#include 

#include "plugin.h"

struct hfp_methods *load_plugin(char *filename)
{
	struct hfp_methods *methods;
	void *handle;
	struct hfp_methods *(*plugin_init)(void);
	char *error;

	handle = dlopen(filename, RTLD_LAZY);
	if (!handle) {
		fprintf(stderr, "%s\n", dlerror());
		return NULL;
	}
	/* clear any existing errors */
	dlerror();

	*(void **) (&plugin_init) = dlsym(handle, "hfp_plugin_init");

	if ((error = dlerror()) != NULL) {
		fprintf(stderr, "%s\n", error);
		return NULL;
	}
	methods = (*plugin_init)();

	return methods;
}

int main(void)
{
	char *filename = "./test.so";
	struct hfp_methods *methods = NULL;

	methods = load_plugin(filename);
	if (methods == NULL) {
		fprintf(stderr, "The plugin load failed.\n");
		return 1;
	}
	fprintf(stderr, "Plugin loaded successfully.\n");

	methods->hello();
	methods->bye();

	return 0;
}