Dynamic Library Function Call
Question
I have the following code which simply loads the library test.so from the current directory and executes the version
function within that library. What should be returned is a string. What is instead returned is junk from the stack(a pointer location maybe?). Does anyone have any idea why the following code would be failing.
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv){
void *handler;
char *(*version);
char *error;
handler = dlopen("./test.so", RTLD_LAZY);
if(!handler){
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); //Flushes any existing error
*(void **)(&version) = dlsym(handler, "version");
if((error = dlerror()) != NULL){
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
printf("%s\n", version);
dlclose(handler);
exit(EXIT_SUCCESS);
}
Solution
Change the declaration:
char *(*version); // this is not a function pointer
to:
char *(*version)(); // but this is
then, change the line:
printf("%s\n", version);
to:
printf("%s\n", version());
OTHER TIPS
dlsym just returns a function pointer. You still need to actually call it, which you can do by casting the (void*) to a function pointer of the appropriate type and calling that.
There are two errors in your code:
The declaration of version
: it is a pointer to a pointer to char in your code, which led you to a weird conversion in:
*(void **)(&version) = dlsym(handler, "version");
Instead use a pointer to function returning pointer to char, like so:
char *(*version)();
and use a regular assignment:
version = dlsym(handler, "version");
You are not calling the function, when you print the result. In C, writing just the function name returns its address, so version
and &version
are equivalent. Your code should be like:
printf("%s\n", version());