Alternatives to dlsym() and dlopen() in C++

c++, dlsym, dynamic-loading, shared-libraries

Solution

The common solution to your problem is to declare a table of function pointers, to do a single dlsym() to find it, and then call all the other functions through a pointer to that table. Example (untested):

// libfoo.h
struct APIs {
   void  (*api1)(void);
   void *(*api2)(int);
   long  (*api3)(int, void *);
};

// libfoo.cc
void fn1(void) { ... }
void *fn2(int) { ... }
long fn3(int, void *) { ... }

APIs api_table = { fn1, fn2, fn3 };


// client.cc
#include "libfoo.h"
...
  void *foo_handle = dlopen("libfoo.so", RTLD_LAZY);
  if (!foo_handle) {
     return false;            // library not present
  }
  APIs *table = dlsym(foo_handle, "api_table");
  table->api1();              // calls fn1
  void *p = table->api2(42);  // calls fn2
  long x = table->api3(1, p); // calls fn3

P.S. Accessing your API functions individually using dlsym and pointers does not in itself lead to memory corruption and crashes. Most likely you just have bugs.

EDIT: You can use this exact same technique with a 3rd-party library. Create a `libdrmaa_wrapper.so` and put the `api_table` into it. Link the wrapper directly against `libdrmaa.so`.

In the main executable, `dlopen("libdrmaa_wrapper.so", RTLD_NOW)`. This `dlopen` will succeed if (and only if) `libdrmaa.so` is present at runtime and provides all API functions you used in the `api_table`. If it does succeed, a single `dlsym` call will give you access to the entire API.

Problem

I have an application a part of which uses shared libraries. These libraries are linked at compile time. At Runtime the loader expects the shared object to be in the `LD_LIBRARY_PATH` , if not found the entire application crashes with error "unable to load shared libraries".Note that there is no guarantee that client would be having the library, in that case I want the application to leave a suitable error message also the independent part should work correctly. For this purpose I am using `dlsym()` and `dlopen()` to use the API in the shared library. The problem with this is if I have a lot of functions in the API, i have to access them Individually using `dlsym()` and ptrs which in my case are leading to memory corruption and code crashes. Are there any alternatives for this?

Original source