Let me apologise upfront for the long question. It is as short as I could make it, which is, unfortunately, not very short.
I have defined two interfaces, A and B:
class A // An interface
{
public:
virtual ~A() {}
virtual void whatever_A()=0;
};
class B // Another interface
{
public:
virtual ~B() {}
virtual void whatever_B()=0;
};
Then, I have a shared library "testc" constructing objects of class C, implementing both A and B, and then passing out pointers to their A-interface:
class C: public A, public B
{
public:
C();
~C();
virtual void whatever_A();
virtual void whatever_B();
};
A* create()
{
return new C();
}
Finally, I have a second shared library "testd", which takes a A*
as input, and tries to cast it to a B*
, using dynamic_cast
void process(A* a)
{
B* b = dynamic_cast<B*>(a);
if(b)
b->whatever_B();
else
printf("Failed!\n");
}
Finally, I have main application, passing A*
's between the libraries:
A* a = create();
process(a);
If I build my main application, linking against the 'testc' and 'testd' libraries, everything works as expected. If, however, I modify the main application to not link against 'testc' and 'testd', but instead load them at runtime using dlopen
/dlsym
, then the dynamic_cast
fails.
I do not understand why. Any clues?
I found the answer to my question here. As I understand it, I need to make the typeinfo available in 'testc' available to the library 'testd'. To do this when using dlopen()
, two extra things need to be done:
-E
option, to make sure it exports all symbols to the executable, not just the ones that are unresolved in it (because there are none)dlopen()
, add the RTLD_GLOBAL
option, to make sure symbols exported by testc
are also available to testd
In general, gcc does not support RTTI across dlopen boundaries. I have personal experience with this messing up try/catch, but your problem looks like more of the same. Sadly, I'm afraid that you need to stick to simple stuff across dlopen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With