Call a function in a shared library

From Rosetta Code
Revision as of 15:32, 6 March 2009 by rosettacode>ShinTakezou (new task with C code; category?)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Call a function in a shared library
You are encouraged to solve this task according to the task description, using any language you may know.

Show how to call a function in a shared library (without dynamically linking to it at compile-time). In particular, show how to call the shared library function if the library is available, otherwise use an internal equivalent function.

C

Works with: POSIX version .1-2001

Tested with gcc on a GNU/Linux system (on GNU/Linux dl* functions are available linking to libdl, i.e. with -ldl option)

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <dlfcn.h>

int myopenimage(char *in) {

 static int handle=0;
 fprintf(stderr, "internal openimage opens %s...\n", in);
 return handle++;

}

int main() {

 void *imglib;
 int (*extopenimage)(char *);
 int imghandle;
 imglib = dlopen("./fakeimglib.so", RTLD_LAZY);
 if ( imglib != NULL ) {
   /* extopenimage = (int (*)(char *))dlsym(imglib,...)
      "man dlopen" says that C99 standard leaves casting from
      "void *" to a function pointer undefined. The following is the
      POSIX.1-2003 workaround found in man */
   *(void **)(&extopenimage) = dlsym(imglib, "openimage");
   /* the following works with gcc, gives no warning even with
      -Wall -std=c99 -pedantic options... :D */
   /* extopenimage = dlsym(imglib, "openimage"); */
   imghandle = extopenimage("fake.img");
 } else {
   imghandle = myopenimage("fake.img");
 }
 printf("opened with handle %d\n", imghandle);
 /* ... */
 if (imglib != NULL ) dlclose(imglib);
 return EXIT_SUCCESS;

}</lang>

The fake fakeimglib.so code is

<lang c>#include <stdio.h> /* gcc -shared -nostartfiles fakeimglib.c -o fameimglib.so */ int openimage(char *s) {

 static int handle = 100;
 fprintf(stderr, "opening %s\n", s);
 return handle++;

}</lang>

When the library fakeimglib.c exists in the current directory (this choice is senseful only for testing purposes), the output is:

opening fake.img
opened with handle 100

otherwise the output is:

internal openimage opens fake.img...
opened with handle 0