Call a function in a shared library
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.
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
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>
- include <stdlib.h>
- 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