// foo.c
// represents the XS lib referencing a symbol (lgamma) in an external
+library libm.so
#include <math.h>
double foo() {
return lgamma(42.0);
}
// mytest.c
// this is just a wrapper which essentially does what perl/DynaLoader
+is doing,
// i.e. loading the XS lib (Foo.so) dynamically at runtime
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main()
{
double (*foo)(void);
char *error;
printf("dynamically loading 'Foo.so'...\n");
void *so = dlopen("Foo.so", RTLD_LAZY);
if (!so) {
fprintf(stderr, "%s\n", dlerror()); exit(1);
}
dlerror();
*(void **) (&foo) = dlsym(so, "foo");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error); exit(1);
}
printf("%f\n", (*foo)());
dlclose(so);
exit(0);
}
Run the following commands
gcc -c -fPIC foo.c # compile
gcc -shared -o Foo.so foo.o # create/link shared library F
+oo.so
gcc -rdynamic -o mytest mytest.c -ldl # create wrapper executable wh
+ich loads Foo.so
Note that there are no errors while linking Foo.so, even though the command is missing the appropriate link instruction -lm referencing the math library! As I pointed out, the shared library is created just fine.
Now, if you try to execute it you get the expected "undefined symbol" error at runtime:
$ LD_LIBRARY_PATH=. ./mytest
dynamically loading 'Foo.so'...
./mytest: symbol lookup error: ./Foo.so: undefined symbol: lgamma
while if you link Foo.so with -lm (which corresponds to the step missing in the OP), everything works fine:
$ gcc -shared -o Foo.so foo.o -lm
$ LD_LIBRARY_PATH=. ./mytest
dynamically loading 'Foo.so'...
114.034212
|