
I posted this to this list ones before (as the site sugests), and didn't get any response, possibly becource it is simply to useless for you guys to reply to, but I'm not sure. If it is indeed useless please let me know, so I know not to put any effort in it. The Open Computer Forensics Architecture Library (OcfaLib) hides a litle piece of template code for loading a class from a dynamically loaded library. Although this code is currently bound to OcfaLib and usage on *NIX systems, I wondered if the concept used would not be extendable to a generically usable library for this purpose. I've tried to strip the OCFA specific code to show the simple templating concept of this library. I would like to know if it is a good idea to work on this code in order to make it a powerfull cross-platform boost library that addresses this issue in an even more generic way. If it is useless, please also let me know. First lets show an example of usage: typedef SinglePointerConstructor<AbstractRepository,const char> CRepositoryType; PolicyLoader<CRepositoryType> pl(myLib,"createRepository"); CRepositoryType *constructor=pl.constructor(); _instance = (*constructor)(repRoot.c_str()); Here the 'AbstractRepository *' type _instance gets assigned a new object of a class that implements AbstractRepository to it, that is created with the "createRepository" function in the so file designated by myLib. Here is the stripped down template code: ---------------------------------- template <class T,class U> class SinglePointerConstructor { public: typedef T * (*fp)(U *); SinglePointerConstructor (fp func) : mFunction(func) {} T *operator() (U *val) { return (mFunction)(val); } private: fp mFunction; }; template <class T> class VoidToFunction { public: static T *cast(void *p) { #ifdef VOID_FP_CAST_WORKAROUND #ifdef POINTERS_64BIT return new T(reinterpret_cast<typename T::fp>(reinterpret_cast<long long>(p))); #else return new T(reinterpret_cast<typename T::fp>(reinterpret_cast<int>(p))); #endif #else return new T(reinterpret_cast<typename T::fp>(p)); #endif }; }; class PolicyLoader: { public: PolicyLoader(std::string myLib,std::string loadername):mLibHandle(0),mConstructor(0) { mLibHandle=dlopen(myLib.c_str(),RTLD_NOW|RTLD_GLOBAL); if (mLibHandle == 0) { throw std::runtime_error( std::string("Problem loading library '") + myLib + std::string("' (") + std::string(dlerror()) + std::string(")") ); } mConstructor = VoidToFunction<TConstructor>::cast(dlsym(mLibHandle,loadername.c_str())); if (mConstructor == 0) { std::string errString=std::string("Problem looking up symbol '") + loadername + std::string("' in library '") + myLib + std::string("' (") + std::string(dlerror()) + std::string(")"); dlclose(mLibHandle); throw std::runtime_error(errString); } } ~PolicyLoader() { delete mConstructor; } void closeLib() { if (mLibHandle) { dlclose(mLibHandle); } mLibHandle=0; } TConstructor *constructor() { return mConstructor; } private: void *mLibHandle; TConstructor *mConstructor; }; -----------------