It looks like a problem with g++. The code I was talking about is in a
shared library. When I link the executable statically dynamic_cast works.
When I use however the shared library dynamic_cast returns 0. Same code but
different behavior due to linking.
There is a section "dynamic_cast, throw, typeid don't work with shared
libraries" at
http://gcc.gnu.org/faq.html#dso. From what I understand though
there is not much you can do? I'm using version 3.4.6 of g++ which is the
latest of the 3.4.x series.
Boris, this is a very general problem in C++, coupled with
both compiler, library, and linker problems. It's all about
requirements for uniqueness.
Here is a formula to make it all work reliably,
but first definitions:
A *module* is either a shared library or executable
A type is *critical* if it is shared between modules
and must be unique.
* Do not use inline functions for critical types
-- this forces the RTTI and vtable to be in
a specific object file
* if two libraries A,B share some critical entity X, X must
be instantiated in a third library D on which
both A and B depend: they must be linked against D
at compile time.
If you follow these rules everything will work.
You can relax the first rule if you know what member functions
haul in the vtable/rtti.
Example: you have three libraries A, B, and C which are
loaded as plugins in various combinations, and can be
unloaded too! They communicate by dynamic casting or
exceptions, for a type X.
Make sure there is a library D containing X.
Link A,B,C against D.
If you do this, there will be ONE instance of X in D,
and D will remain loaded whilst any one of A,B,C is
loaded. D may be unloaded and reloaded if A,B,C
are all unloaded, and X may end up with a different
address in that case, but you cannot tell except
by 'cheating' such as saving the address as a void*
in the mainline. If that happens .. well you broke
the second rule, since the mainline actually
depended on X and you didn't link D to it in such
a way the dependence is manifest, which is what
the second rule requires. This is very unlikely
to happen, except with debugging code.