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