Dynamic binding of an Interface from a Dynamic loaded DLL class IRenderer { public: virtual ~IRenderer( ) { } virtual int Init( int ) = 0; }; //DLL Header: DllName.h #ifdef DLLNAME_EXPORTS # define CLASS_DECLSPEC __declspec(dllexport) #else # define CLASS_DECLSPEC __declspec(dllimport) #endif #include "RendererInterface.h" template<class T> class TSingleton { private: static T* object; static int refcount; public: TSingleton( ) { if( !refcount++ ) object = new T; } ~TSingleton( ) { if( !--refcount ) { delete object; object = NULL; } } const T& GetObject( ) { return *object; } static void* operator new( size_t ) { return NULL; } static void* operator new[]( size_t ) { return NULL; } static const int& RefCount( ) { return refcount; } }; template<class T>T* TSingleton<T>::object = NULL; template<class T>int TSingleton<T>::refcount = 0; class CD3d : public IRenderer { public: virtual ~CD3d( ) { } virtual int Init( int ); }; int CD3d::Init( int i ) { return ++i; } //DLL Source: DllName.cpp static bool wasCreated = false; extern "C" { CLASS_DECLSPEC IRenderer* __cdecl CreateInstance( ) { static TSingleton<CD3d> d3d; wasCreated = true; return const_cast<CD3d*>( &d3d.GetObject( ) ); } CLASS_DECLSPEC IRenderer* __cdecl GetInstance( ) { assert( false != wasCreated ); TSingleton<CD3d> d3d; return const_cast<CD3d*>( &d3d.GetObject( ) ); } } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } //Application SceneGraph Header: sg.h class CSceneGraph { private: typedef IRenderer* (__cdecl * funcCreateInstance)( ); IRenderer* iRen; HMODULE hMod; funcCreateInstance CreateInstance; public: CSceneGraph( ) { hMod = LoadLibrary( "dllname.dll" ); CreateInstance = reinterpret_cast<funcCreateInstance>( GetProcAddress( hMod, "CreateInstance" ) ); iRen = CreateInstance( ); //i should return 1 if binding worked int i = iRen->Init( 0 ); } ~CSceneGraph( ) { FreeLibrary( hMod ) } }
No comments: