Search code examples
c++shared-librariesdlopenname-mangling

Use of application class within shared library


I'm trying to create a "gaming platform" that lets the user choose a game to play and also the graphic library to render it. Those games and graphic libraries are implemented as dynamic libraries, loaded at runtime. We'll call the gaming platform Core. The shared libraries contain classes that are loaded at run-time with RTLD_LAZY flag, nevertheless if I load it with RTLD_NOW the program compiles correctly. I've followed this tutorial in order to avoid name mangling and like this use classes defined on the shared libraries. For the moment, if the methods doesn't call any method of the Core class (only use parameters of the class) it works just fine. (see code below)

// Working code

void libNCurses::refreshScreen(Core *core)
{
  if (core->input != Input::None)
        mvaddch(0,0,'c');
  else
        mvaddch(0,0,' ');
  refresh();
}

But when I want to call some method of the Core class, then the program crashes complaining about undefined symbol (the symbol of the used method). (see code below)

// Not working code

void libNCurses::refreshScreen(Core *core)
{
  std::vector<Object *> objs = core->getObjects();

  for (auto obj = objs.begin(); obj != objs.end(); obj++)
      mvaddch(10, 10, 'O');
  if (core->input != Input::None)
        mvaddch(0,0,'c');
  else
        mvaddch(0,0,' ');
  refresh();
}

Of course the Core header is included on the shared library. Anyone could explain me why is this happening and how to fix it?


Solution

  • Okay, after reading Drepper's paper How to write shared libraries I've found what the problem was. In C++ the methods are not linked. Nor the program, nor the lib have the methods of the other linked. The patch is to use vtable. If the method is virtual, the program checks the vtable that goes with the object and there founds the function address. I could use lib's methods because to avoid name mangling I was using an interface for the lib, but not in the other way. I expect that this answer helps somebody.