g++ and dynamic_cast
Mihai Donțu
mihai.dontu@gmail.com
Fri Sep 19 11:56:00 GMT 2008
On Friday 19 September 2008, Eljay Love-Jensen wrote:
> Hi Mihai DonÈu,
>
> > Assuming I have a program that loads two shared objects (liba.so and
> > libb.so), is there any way that I can make dynamic_cast work in libb.so
> > for an object obtained from liba.so, without loading liba.so and libb.so
> > with dlopen(...| RTLD_GLOBAL)?
>
> How do you obtain an object from liba.so without loading liba.so?
>
> Isn't libb.so bound to liba.so as a DSO (so that liba.so is loaded
> implicitly by ld when libb.so is dlopen()'d)?
1. I apologise. I'm unable to write emails that make clear sense outside of my
head, when I'm concentrated on something. :) At least, not the first time.
2. if I pass the flag RTLD_GLOBAL to dlopen() when loading both liba.so and
libb.so, then I can use dynamic_cast in libb.so for a C++ object obtained
from liba.so. Otherwise, if I pass only RTLD_LAZY (or RTLD_NOW) the
dynamic_cast fails across shared objects. I guess I'm looking for a way to
obtain the same affect as RTLD_GLOBAL (somehow make all the symbols in
liba.so and libb.so available for global symbol resolution).
This problem appears to be specific to g++3.3.x and earlier. G++ 4.x works
like a charm (much has changed though).
> > Currently, dynamic_cast returns NULL if the shared object (plugin) is
> > loaded with dlopen("liba.so", RTLD_LAZY) (some rtti nastiness).
>
> The dynamic_cast facility relies on the RTTI information.
>
> One way that can be an issue is if the RTTI information is prebound, or if
> it is hidden, or if "vague linkage" is in some other way confounding RTTI.
I need to look more into how g++ 3.x handles RTTI and why it doesn't search
the symbol spaces of other loaded shared objects ...
> Because even though the RTTI structure may contain the same data in liba.so
> and libb.so, it will be at different addresses.
>
> The "are these two objects the same" compares the pointer to the RTTI,
> rather than a comparing the value of the RTTI structure.
>
> You should be able to use 'nm' to view whether or not the RTTI structures
> are external or local. The RTTI structures are affected by the visibility
> flags and the __attribute__((visibility("hidden"))) annotations.
>
> Since I compile my code with -fvisibility=hidden which otherwise causes the
> RTTI information to be local to the "package" (such as libfoo.so), in my
> declaration of my classes, I make sure I do this to expose the RTTI
> information when/where I need to:
>
> class __attribute__((visibility("default"))) Foo
> {
> //...
> };
>
> HTH,
Thanks,
--
Mihai DonÈu
More information about the Gcc-help
mailing list