Dynamic Loading with C

Another memo to myself… today: How to dynamically load a shared library in a C program.

This is neither rocket science nor is it anything new. There are several tutorials and manuals on the web which describe the topic. This is a summary for myself.

Let’s assume we have a library helloWorld containing a special function:

#include <stdio.h>  /* import printf() */

void hello(void)
{
	printf("Hello world!\n");
} 

Then it is possible to construct a program testprog which loads this library on the fly:

#include <dlfcn.h>  /* import dlopen(), dlerror(), dlsym(), dlclose() */
#include <stdio.h>  /* import fprintf */
#include <stdlib.h> /* import exit() */

int main(void)
{
	void *lib;              /* void pointer named lib */
	void (*sayHello)(void); /* void pointer named sayHello */
	const char *error;      /* string to store error messages */
	
	/* open library, resolve all undefined symbols in it (flag RTLD_NOW) */
	lib = dlopen("helloWorld.so", RTLD_NOW);
	if (!lib) /* if lib is undefined: catch error and exit */
	{
		fprintf(stderr,"%s \n", dlerror());
		exit(EXIT_FAILURE);
	}
	
	dlerror(); /* returns the last error; also clears the error cache... */
	
	/* obtain a pointer to the function hello() and convert/typecast it */
	*(void **) (&sayHello) = dlsym(lib, "hello");
	error = dlerror();
	if (error) /* if there is an error: catch it and exit */
	{
		fprintf(stderr,"%s \n", error);
		exit(EXIT_FAILURE);
	}
	
	sayHello();   /* call hello() from helloWorld.so via its pointer */
	dlclose(lib); /* close library, i.e. free memory */
	
	return EXIT_SUCCESS; /* that's all folks */
}

Following Makefile allows to automatically build the files:

all: testprog

clean:
	rm -f testprog helloWorld.o helloWorld.so

helloWorld.so: helloWorld.c
	gcc -shared -Wall -Werror -fPIC -o helloWorld.so helloWorld.c

testprog: testprog.c helloWorld.so
	gcc -Wall -rdynamic -o testprog testprog.c -ldl

Note that the library is not explicitly linked to the program. Only libdl.so is linked via “-ldl”.

In the end we can execute the program “testprog”. But prior to calling testprog the library search path has to be modified so that the custom library (residing in the current directory) is found:

export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
./testprog
unset LD_LIBRARY_PATH

Ok, that’s a complex hello world program, but it shows how to dynamically load external code. I wanted to use the mechanism to program the control nodes in my thesis, but instead I’ll use custom code for my own custom virtual machine.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s