1

I'm trying to build a system, that uses dynamic loaded library files (.so files) as plugins in C++14. I build the project using gcc in combination with qt5.5.1 within qtcreator.
The problem I'm having is, that I don't fully understand, what dlopen() (and dlsym()) actually does and get strange behavior because of it. Here is a simplified (not executable) Version:

/*Kernel.hpp*/
class Kernel{
   int loadPlugins();
}

void* sharedPointer; //The Object location is stored in here


/*Kernel.cpp*/
Kernel::loadPlugins(){

   handle1 = dlopen(<file1>, RTLD_LAZY);
   init_t init = (init_t) dlsym(handle1, "init");  //init_t is just a fitting function pointer
   execute_t exec = (execute_t) dlsym(handle1, "execute");  //same goes for "execute_t"


   handle2 = dlopen(<file2>, RTLD_LAZY);
   init_t init = (init_t) dlsym(handle2, "init");
   execute_t exec = (execute_t) dlsym(handle2, "execute");
}


/*<file1.h>*/

Class Test{
   int func();
   int field = 0;
}


/*<file1.cpp>*/

int Test::func(){/*do stuff*/}

Test* test = NULL;      
extern void* sharedPtr;       //use the ptr from kernel
extern "C" init(){
   test = new Test();
   sharedPtr = (void*)test;   //store address of newly created Test-Object
}

extern "C" execute(){
   /* Do Stuff */
}


/*<file2.h>*/


/*<file2.cpp>*/
Test* test = NULL;      
extern void* sharedPtr;       //use the ptr from kernel
extern "C" init(){
   test = (Test*)sharedPtr;   //get address of Testobject
}

extern "C" execute(){
   std::cout << test->field << std::endl;    //Working perfectly
   std::cout << test->func() << std::endl    //Segmentaion fault

}

The precise Error is a symbol lookup error of a member function with some mangled name (unmangled name is Kernel::test()).

What I think, that should happen: When Kernel.loadPlugins() is called, the first library creates an object, saves its address in the main program. Library reads that address and can use it, as if it had created that object. So the field can be read and written to and the member function can be called.

What actually happens: When Kernel.loadPlugins() is called, the first library creates said object, can use it as expected, saves its address in the main program. Library receives said address as expected, can use the field of said object as expected (it does not matter what type that field has, even other objects, like strings, worked, valgrind does not show any leaks as well), but when it tries to call func() it produces a segmentation fault.

I have two primary doubts - First, I would like to know why that happens? Second, I would like to know if there is a nice way to fix it?

Poehli
  • 307
  • 4
  • 16
  • The C++ standard has close to zero support for dynamic libraries. So it's entirely up to the documentation of the facility you're using. – Cheers and hth. - Alf Nov 29 '16 at 00:17
  • 2
    To continue from your title: ... usually don't work well together. – πάντα ῥεῖ Nov 29 '16 at 00:28
  • Please provide a *minimal* working example that can be built. Which compiler/platform are you using, and with what build flags? As a side note, this is not really a c++14 question. – frasnian Nov 29 '16 at 01:33
  • "When Kernel.loadPlugins() is called, the first library creates said object" - this isn't what's in your example code (you simply query the symbols but do not execute them). Please provide full example which we can repro. – yugr Nov 29 '16 at 07:30
  • Sorry, I tried the past 2 days to create a minimal version, that produces the same error as above, but everything I tried, does not produce that error. Also see my edits for more information about the compiler and the error – Poehli Dec 01 '16 at 16:06

0 Answers0