0

So I have a program separated into 4 parts. I the first 3 parts I create 3 different shared dynamic libraries which I then use in the fourth part with dynamic loading.

In the 4th part I have program structure that roughly looks like this

.hpp

...
typedef Snake *(*SNAKE)(int, int);
typedef void (*DELETESNAKE)(Snake *);

...

SNAKE _snake;
std::map<int, void *> _handlers;
std::map<int, Snake *> _snakes;
std::map<int, std::string> _libs;
...

.cpp

 ...
_handlers[1] = dlopen("lib/libSnakeSFML.so", RTLD_LAZY | RTLD_LOCAL);
if (!_handlers[1])
    throw NibblerExceptionE("dl_error : " + std::string(dlerror()));
_snake = reinterpret_cast<SNAKE>(dlsym(_handlers[1], "createSnake"));
if (!_snake)
    throw NibblerExceptionE("Some snake Error");
_snakes[1] = _snake(_w, _h);
_snakes[1]->init();

_handlers[2] = dlopen("lib/libSnakeSDL.so", RTLD_LAZY | RTLD_LOCAL);
if (!_handlers[2])
    throw NibblerExceptionE("dl_error : " + std::string(dlerror()));
_snake = reinterpret_cast<SNAKE>(dlsym(_handlers[2], "createSnake"));
if (!_snake)
    throw NibblerExceptionE("Some snake Error");
_snakes[2] = _snake(_w, _h);
_snakes[2]->init();

_handlers[3] = dlopen("lib/libSnakeFLTK.so", RTLD_LAZY | RTLD_LOCAL);
if (!_handlers[3])
    throw NibblerExceptionE("dl_error : " + std::string(dlerror()));
_snake = reinterpret_cast<SNAKE>(dlsym(_handlers[3], "createSnake"));
if (!_snake)
    throw NibblerExceptionE("Some snake Error");
_snakes[3] = _snake(_w, _h);
_snakes[3]->init();
...

now when I try to call any of the _snakes[...] methods on the fly, the last handle, which in this case is FLTK, seems to be used. From some research I did, It seems like you can only have one handle in a thread. I'm not sure it I'm saying that correctly, but if I am. How do I work around this?

sassy_rog
  • 1,077
  • 12
  • 30
  • 3
    Sounds like you have UB (or some other bug) elsewhere. I'll say what I'm finding myself saying on almost _every_ question lately, which is: present your [mcve]. – Lightness Races in Orbit Jul 18 '19 at 13:19
  • As mentioned in the answer, is there a reason you’re performing the linking manually at runtime rather than relying on the dynamic link editor? – Konrad Rudolph Jul 18 '19 at 13:30
  • @LightnessRacesinOrbit minimal in this case would be a lot. My work is not very neat. – sassy_rog Jul 18 '19 at 13:47
  • @SASSY_ROG I tried with a minimal example and it worked as expected (which is the main purpose of such dynamic loading mechanism), thus the problem lies in something else you don't show us... – prog-fh Jul 18 '19 at 13:50
  • 3
    @SASSY_ROG The entire purpose of the process of making a [mcve] is to _make_ it neat and to _make_ it minimal. How else can you debug your code? Your bug could be absolutely anywhere. You are expected to do that work up-front before asking. Indeed, in this case, we literally cannot help you until you do. – Lightness Races in Orbit Jul 18 '19 at 13:51
  • @SASSY_ROG To paraphrase Lightness’ entirely correct comment: Yes, *it is a lot of work*. But it’s *necessary* work for debugging, and only you can do this work since only you have the necessary information. We (that is, people on Stack Overflow) can only help you with the steps that come after reducing your problem to a minimal case. – Konrad Rudolph Jul 19 '19 at 13:19

1 Answers1

1

The number of libraries you can keep open simultaneously with dlopen is very large and basically limited by your address space.

man dlopen

Will dlopen yield the same handle for two calls with the same file?

There you can even find an example that stores the handles in an array, just like you seem to do and apparently it works just fine: manydl.c

I just cannot help but wonder why you would not just let the linker link your libraries to your executable instead.

Wolfgang Brehm
  • 1,491
  • 18
  • 21