Search code examples
c++dynamic-library

Local dynamic library


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) {.


Solution

  • 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);
           }