Bernd Strieder wrote: > Looking at > > http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/C++-dlopen-mini-HOWTO.html > which tries to provide a portable solution:
I think I saw that around 2 years ago. It is not even accurate. For example this statement is false: "Classes Another problem with the dlopen API is the fact that it only supports loading functions. But in C++ a library often exposes a class which you would like to use in your program. Obviously, to use that class you need to create an instance of it, but that cannot be easily done." Firstly you can load objects with dlsym, in fact it is better to do so. Casting void * to a function pointer is undefined behaviour whereas casting it to an object is defined as long as it's a valid cast (i.e. you are casting it to the correct type). > You probably have a virtual base class, and you have a derived class > being passed through base class pointers. If both classes have to be > exposed to the executable, then they could be passed from the plugin > independently, by factory methods of their own, and no casting would be > necessary. I have a generic system, thus in simple terms I have a class called Builder which is an abstract base class, then a template we can call it BuilderT which derives from Builder, then all classes derive from BuilderT< T > where T is a base-class. BuilderT inherits public and virtual from Builder. This part is not a problem. You then have a class BuilderFactory which is abstract and derives from DLObject and the symbols that are loaded with dlsym all derive from BuilderFactory (and thus from DLObject. Now the casting here works fine. Then the loaded BuilderFactory is invoked to create its builder (just once) and does so fine too. It is when you try to cast the Builder to the BuilderT that the cast is not always working correctly. The failure seems to happen when one "plugin" (shared-object library) tries to cast a builder from another "plugin", i.e. both libraries have been loaded with dlopen. This happens because an object in one library needs a reference (well shared pointer actually) with an object in the other. > A second option might be a user-defined cast, i.e. a virtual member > function in the base class returning a pointer to the derived class, > returning 0 by default, overwritten in the derived class to do the > right thing. > Both options have the disadvantage, that those classes you want to be > able to cast to become part of the overall plugin interface. It would > not work, if all plugins required it. That would be possible as the Builder interface can enforce it. It would not apply to every abstract or base class in general because there are no restrictions regarding them, except that the concrete classes have to take their components as shared pointers. How would one do this though? Because there is no such thing as a virtual template function (and rightly so) so something like: template < typename T > virtual bool supportsInterface( T* & ptr ); (where T is the type you are trying to cast to and it sets ptr to this or 0 and returns true/false) is not possible in C++. > A third option for verifying purposes could be a user-defined rtti > function returning a specific id for every class. Possible and what I might have to revert to. I think that's how COM does it (with their horrible UUIDs thus no need to make that function up there a template). > Whatever, a not failing dynamic_cast has to be in the code of the plugin. Yes. Now I call dlopen with RTLD_LAZY. Is that the correct option? Should I use a different parameter? > dynamic_cast is necessary in some cases, or it would not exist. Coding > around it is about as ugly as the cast itself. which is why I put it in the low-level library code only and business code will not be doing any casting. I will try a bit harder to get this to work because I don't want to have to try my own casting system (supposedly you check then do static_cast?) _______________________________________________ help-gplusplus mailing list help-gplusplus@gnu.org http://lists.gnu.org/mailman/listinfo/help-gplusplus