#include #include #include #ifdef cpPlugins_OS_Windows # include #else // cpPlugins_OS_Windows # include #endif // cpPlugins_OS_Windows // ------------------------------------------------------------------------- void cpPlugins::OS::DLLManager:: TeaseLoadedLibraries( ) { void* hnd = cpPlugins::OS::DLLManager::_Load( "", 0 ); if( hnd == NULL ) throw std::runtime_error( "Something really nasty just happened." ); } // ------------------------------------------------------------------------- void cpPlugins::OS::DLLManager:: GetPluginsLibraryContents( std::map< std::string, std::set< std::string > >& filters, const std::string& libname ) { typedef const char* ( *_TFunction )( ); // Load library void* hnd = cpPlugins::OS::DLLManager::_Load( libname, RTLD_LAZY ); if( hnd == NULL ) throw std::runtime_error( "Something nasty just happened." ); // Get library contents filters.clear( ); _TFunction descriptors_func = NULL; try { descriptors_func = reinterpret_cast< _TFunction >( cpPlugins::OS::DLLManager::_Sym( hnd, "cpPlugins_LoadedFilters" ) ); } catch( ... ) { } if( descriptors_func != NULL ) { std::string descriptors = descriptors_func( ); std::vector< std::string > tokens; cpPlugins::Tokenize( tokens, descriptors, ";" ); for( auto t : tokens ) { std::size_t pos = t.find( ":" ); filters[ t.substr( 0, pos ) ].insert( t.substr( pos + 1 ) ); } // rof cpPlugins::OS::DLLManager::_UnLoad( hnd ); } else { cpPlugins::OS::DLLManager::_UnLoad( hnd ); throw std::runtime_error( std::string( "Library \"" ) + libname + std::string( "\" not recognized as a cpPlugins library" ) ); } // fi } // ------------------------------------------------------------------------- void* cpPlugins::OS::DLLManager:: LoadPlugins( const std::string& lname ) { return( cpPlugins::OS::DLLManager::_Load( lname, RTLD_NOW | RTLD_GLOBAL ) ); } // ------------------------------------------------------------------------- void* cpPlugins::OS::DLLManager:: LoadCreator( void* lib_hnd, const std::string& category, const std::string& name ) { return( cpPlugins::OS::DLLManager::_Sym( lib_hnd, ( category + "_" + name ).c_str( ) ) ); } // ------------------------------------------------------------------------- #ifdef cpPlugins_OS_Windows #else // cpPlugins_OS_Windows namespace cpPlugins { namespace OS { /** */ struct link_struct { void* pointers[ 3 ]; struct link_struct* ptr; }; /** */ struct link_map { void* address; char* path; void* not_needed; struct link_map* next; struct link_map* prev; }; } // ecapseman } // ecapseman #endif // cpPlugins_OS_Windows // ------------------------------------------------------------------------- void* cpPlugins::OS::DLLManager:: _Load( const std::string& libname, int flags ) { void* return_handle = NULL; #ifdef cpPlugins_OS_Windows #else // cpPlugins_OS_Windows std::queue< std::string > q; std::set< std::string > m; q.push( libname ); while( !q.empty( ) ) { // Get next filename std::string lname = q.front( ); q.pop( ); if( m.find( lname ) != m.end( ) ) continue; // Get library handle (main program vs. linked libraries) void* h = NULL; if( lname != "" ) { if( lname == libname ) { h = dlopen( lname.c_str( ), flags ); return_handle = h; } else h = dlopen( lname.c_str( ), RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE ); } else { h = dlopen( NULL, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE ); return_handle = h; } // fi char* err = dlerror( ); if( err != NULL ) throw std::runtime_error( err ); // Process data if( h != NULL ) { link_struct* p = reinterpret_cast< link_struct* >( h )->ptr; if( p != NULL ) { m.insert( lname ); link_map* m = reinterpret_cast< link_map* >( p->ptr ); while( m != NULL ) { q.push( m->path ); m = m->next; } // elihw } // fi } // fi } // elihw #endif // cpPlugins_OS_Windows return( return_handle ); } // ------------------------------------------------------------------------- void* cpPlugins::OS::DLLManager:: _Sym( void* hnd, const std::string& symname ) { void* s = NULL; #ifdef cpPlugins_OS_Windows #else // cpPlugins_OS_Windows s = dlsym( hnd, symname.c_str( ) ); char* err = dlerror( ); if( err != NULL ) throw std::runtime_error( err ); #endif // cpPlugins_OS_Windows return( s ); } // ------------------------------------------------------------------------- void cpPlugins::OS::DLLManager:: _UnLoad( void* hnd ) { #ifdef cpPlugins_OS_Windows #else // cpPlugins_OS_Windows if( hnd != NULL ) { dlclose( hnd ); char* err = dlerror( ); if( err != NULL ) throw std::runtime_error( err ); } // fi #endif // cpPlugins_OS_Windows } /* TODO void* cpPlugins::OS::DLLManager:: Load( const std::string& fname, std::string& error ) { void* hnd = NULL; #ifdef cpPlugins_OS_Windows UINT old = ::SetErrorMode( SEM_FAILCRITICALERRORS ); ::SetErrorMode( old | SEM_FAILCRITICALERRORS ); hnd = ::LoadLibraryA( fname.c_str( ) ); ::SetErrorMode( old ); if( hnd == NULL ) error = "Could not load library."; #else // cpPlugins_OS_Windows hnd = dlopen( fname.c_str( ), RTLD_LAZY | RTLD_GLOBAL ); if( hnd == NULL ) error = dlerror( ); else dlerror( ); #endif // cpPlugins_OS_Windows return( hnd ); } // ------------------------------------------------------------------------- void cpPlugins::OS::DLLManager:: UnLoad( void* hnd ) { #ifdef cpPlugins_OS_Windows ::FreeLibrary( ( HMODULE )hnd ); #else // cpPlugins_OS_Windows dlclose( hnd ); #endif // cpPlugins_OS_Windows } // ------------------------------------------------------------------------- void* cpPlugins::OS::DLLManager:: GetFunctionHandle( void* hnd, const std::string& function ) { void* f = NULL; if( hnd != NULL ) { #ifdef cpPlugins_OS_Windows f = ::GetProcAddress( ( HMODULE )hnd, function.c_str( ) ); #else // cpPlugins_OS_Windows f = dlsym( hnd, function.c_str( ) ); #endif // cpPlugins_OS_Windows } // fi return( f ); } */ // eof - $RCSfile$