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