]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/OS/DLLManager.cxx
Cast image filter added. ROI filter modified.
[cpPlugins.git] / lib / cpPlugins / OS / DLLManager.cxx
index 274c7dc208a76e697bfac59f591a5998477bae4e..c8024c0d088fe8d225d01d1c1a6c2b9f81cb3c71 100644 (file)
 #include <cpPlugins/OS/DLLManager.h>
-
-#ifdef cpPlugins_SYS_WINDOWS
+#include <cpPlugins/Utility.h>
+#include <queue>
+#ifdef cpPlugins_OS_Windows
 #  include <Windows.h>
-#else // cpPlugins_SYS_WINDOWS
+#else // cpPlugins_OS_Windows
 #  include <dlfcn.h>
-#endif // cpPlugins_SYS_WINDOWS
+#endif // cpPlugins_OS_Windows
 
 // -------------------------------------------------------------------------
-void* cpPlugins::OS::DLLManager::
-Load( const std::string& fname, std::string& error )
+void cpPlugins::OS::DLLManager::
+TeaseLoadedLibraries( )
 {
-  void* hnd = NULL;
-#ifdef cpPlugins_SYS_WINDOWS
-  hnd = ::LoadLibraryA( fname.c_str( ) );
-#else // cpPlugins_SYS_WINDOWS
-  hnd = dlopen( fname.c_str( ), RTLD_LAZY | RTLD_GLOBAL );
+  void* hnd = cpPlugins::OS::DLLManager::_Load( "", 0 );
   if( hnd == NULL )
-    error = dlerror( );
-  else
-    dlerror( );
-#endif // cpPlugins_SYS_WINDOWS
-  return( hnd );
+    throw std::runtime_error( "Something really nasty just happened." );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::OS::DLLManager::
-UnLoad( void* hnd )
+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 )
 {
-#ifdef cpPlugins_SYS_WINDOWS
-  ::FreeLibrary( ( HMODULE )hnd );
-#else // cpPlugins_SYS_WINDOWS
-  dlclose( hnd );
-#endif // cpPlugins_SYS_WINDOWS
+  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::
-GetFunctionHandle( void* hnd, const std::string& function )
+_Sym( void* hnd, const std::string& symname )
 {
-  void* f = NULL;
+  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 )
   {
-#ifdef cpPlugins_SYS_WINDOWS
-    f = ::GetProcAddress( ( HMODULE )hnd, function.c_str( ) );
-#else // cpPlugins_SYS_WINDOWS
-    f = dlsym( hnd, function.c_str( ) );
-#endif // cpPlugins_SYS_WINDOWS
+    dlclose( hnd );
+    char* err = dlerror( );
+    if( err != NULL )
+      throw std::runtime_error( err );
+
   } // fi
-  return( f );
+#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$