--- /dev/null
+#include <cpPlugins/OS/DLLManager.h>
+#include <cpPlugins/Utility.h>
+#include <queue>
+#ifdef cpPlugins_OS_Windows
+# include <Windows.h>
+#else // cpPlugins_OS_Windows
+# include <dlfcn.h>
+#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$