Right off the bat, I want to say that I've never worked with dynamic libraries so It's possible that I don't even understand how they work properly.
I want to have a fully loaded code running and after some trigger (probably user interaction) I want to load a specific library and execute a function inside that library. Preferably close it afterwards. Essentially allowing me to change it and re-load it during run time.
This is the simple dynamic library (called dynlib.so located in the same directory as the main code):
int getInt(int arg_0)
{
return (arg_0 + 7);
}
And this is the main program:
#include <iostream>
#include <dlfcn.h>
int main() {
void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW);
if (!lib_handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
typedef int (*func_ptr)(int);
func_ptr func = (func_ptr)dlsym(lib_handle, "getInt");
std::cout << func(13);
dlclose(lib_handle);
}
I'm compiling it using: g++ -std=c++11 -ldl loadlibtest.cpp -o main.
The error I'm catching is ./libshared.so: file too short In my if (!lib_handle) {
.
It works fine for me. I've compiled dynlib.so with
$ gcc dynlib.c -fPIC -shared -o dynlib.so
(Obviously, you need to either compile it as C or C++ with extern "C"
to avoid name mangling).
and I needed to place -ldl
after the source file in the g++
invocation.
gcc: 4.8.5; g++: 5.3.0
dlsym
may fail too and casting from void* to function pointers is technically UB. You should base it on the usage snippet from the
manpage(modified for your function):
dlerror(); /* Clear any existing error */
/* Writing: func = (int (*)(int)) dlsym(handle, "getInt");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
The assignment used below is the POSIX.1-2003 (Technical
Corrigendum 1) workaround; see the Rationale for the
POSIX specification of dlsym(). */
*(void **) (&func) = dlsym(handle, "getInt");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}