Prev: Compile time hooks, like: AClass<SomeType,Hooks<FunctorOne,FunctorTwo,...> >
Next: Why you should never use a const& parameter to initialize a const& member variable!
From: Phoenix87 on 7 Feb 2010 16:11 Hallo everybody I want to build some shared libraries from C++ code defining classes because I want to load them dynamically in programs that need that classes. I've read about dlopen and co., which require the implementation of factory procedures in order to dynamically allocate class instances from the loaded shared object. Is there an alternative way to dynamically load classes in C++ programs? I mean something which allows to instantiate new class instances with new keyword etc...Basically my question is quite the same thing as asking how the STL, or the CERN ROOT libraries work. Thanks in advice! Gab. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Goran on 8 Feb 2010 03:59
On Feb 8, 10:11 am, Phoenix87 <phoenix1...(a)gmail.com> wrote: > Hallo everybody > > I want to build some shared libraries from C++ code defining classes > because I want to load them dynamically in programs that need that > classes. I've read about dlopen and co., which require the > implementation of factory procedures in order to dynamically allocate > class instances from the loaded shared object. Is there an alternative > way to dynamically load classes in C++ programs? I mean something > which allows to instantiate new class instances with new keyword > etc... I think that you have two questions to answer to yourself: 1. do you want to be compiler-agnostic? If yes, then you should drop idea of having C++ interface to your classes and stick with C. This is because C++ language does not define "binary" interface for shared libraries (heck, it does not even define shared libraries in the OS sense). So when you build your library with a C++ compiler/linker, someone with another compiler/linker might find it impossible to use. (BTW, C language doesn't define binary module interface either; that is typically the job of the OS, and all follows from there, starting with C...). If not, then you can continue down the route apparently described in articles you found on the net. 2. do you really want to load your dynamic library at arbitrary point at run-time? I am asking this because you say that you want something like STL (I presume here that you mean standard C++ library, of which STL is only a part). If all you want is a C++ library � la standard C+ + library, then you don't want dynamic loading, and all you need to do is to build a shared library. If, on top of that, you don't mind being compiler-dependent, then just look upon *.so/*.dll creation in your C+ + compiler documentation and drop dlopen etc. If you __do__ want to be compiler-agnostic, you should stick to pure C interface, or find some "integration" technology � la COM (but COM is for Windows, and I don't know of anything vastly adopted that works in- process on Unix clones). If you opt for C interface, you write a shared library using an approach e.g. like this: "exported" part, e.g. MyLib.hpp. extern "C" { struct OpaqueObjectHandle {}; OpaqueObjectHandle* CreateObject(params); void DestroyObject(OpaqueObjectHandle* pobj); ResultType Operation1(OpaqueObjectHandle* pobj, params); // Other operations }; "implementation" part, e.g. MyLib.cpp class Object : public OpaqueObjectHandle { Object(params) {...} ResultType Operation1(params); }; OpaqueObjectHandle* CreateObject(params) { try { return new Object(params); } catch(const std::exception& e) { return Error(e); } void DestroyObject(OpaqueObjectHandle* pobj) { delete static_cast<Object*>(pobj); } ResultType Operation1(OpaqueObjectHandle* pobj, params) { try { static_cast<Object*>(pobj)->Operation1(params); } catch(const std::exception& e) { return Error(e); } } In essence: you expose opaque class "handle", creation/destruction functions and operations. In implementation, you derive actual implementation from said "handle" and simply forward calls.Due to C interface, you need to prevent any exceptions from escaping module boundary. Note that if you do all that, you are very close to the ability to use dynamic loading as well: your user loads the library, loads functions needed, presto. In fact, he can easily write a "facade" class that would hide dynamic loading details. Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |