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

后端 未结 5 807
北荒
北荒 2020-12-07 17:55

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 <

5条回答
  •  醉梦人生
    2020-12-07 18:49

    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.

提交回复
热议问题