X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface.cxx;h=1d883736b1af1fffdf9350921c756e500626586a;hb=d300d9869563bae0ac020e7ed00a5a9905c897fb;hp=259288243d5a309e803115bddb6e50a98645b210;hpb=f533290f40279617e54e19086dde7c0ba9b07f5b;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface.cxx b/lib/cpPlugins/Interface.cxx index 2592882..1d88373 100644 --- a/lib/cpPlugins/Interface.cxx +++ b/lib/cpPlugins/Interface.cxx @@ -5,6 +5,7 @@ #else // cpPlugins_SYS_WINDOWS # include #endif // cpPlugins_SYS_WINDOWS +#include // ------------------------------------------------------------------------- cpPlugins::Interface:: @@ -64,6 +65,7 @@ SaveConfiguration( const std::string& filename ) const for( ; dIt != this->m_DynLibraries.end( ); ++dIt ) out << dIt->first << std::endl; out.close( ); + return( true ); } // ------------------------------------------------------------------------- @@ -72,11 +74,25 @@ LoadPluginFile( const std::string& filename ) { // Open library with its canonical path name auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename ); + if( canonical_fn == "" ) + throw std::runtime_error( + std::string( "cpPlugins::Interface: Library \"" ) + + filename + + std::string( "\" does not exist." ) + ); + + // Check if it was already loaded + if( + this->m_DynLibraries.find( canonical_fn ) != this->m_DynLibraries.end( ) + ) + return; + + // Ok, try to load the library void* hnd = Self::_DLOpen( canonical_fn ); if( hnd == NULL ) throw std::runtime_error( std::string( "cpPlugins::Interface: Could not load library \"" ) + - canonical_fn + + filename + std::string( "\"" ) ); @@ -104,7 +120,7 @@ LoadPluginFile( const std::string& filename ) if( new_filter ) { // Update filters container - TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt ); + auto creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt ); if( creator != NULL ) { this->m_DynFilters[ catIt->first][ *clsIt ] = @@ -127,6 +143,41 @@ LoadPluginFile( const std::string& filename ) Self::_DLClose( hnd ); } +// ------------------------------------------------------------------------- +unsigned int cpPlugins::Interface:: +LoadPluginDir( const std::string& dirname ) +{ + DIR* dir; + struct dirent* ent; + unsigned int count = 0; + if( ( dir = opendir( dirname.c_str( ) ) ) != NULL ) + { + while( ( ent = readdir( dir ) ) != NULL ) + { + try + { + this->LoadPluginFile( + dirname + + std::string( "/" ) + + ent->d_name + ); + count++; + } + catch( ... ) + { + // Ignore errors + } // yrt + } // elihw + closedir( dir ); + } + else + throw std::runtime_error( + std::string( "cpPlugins::Interface: Could not load directory " ) + + std::string( "\"" ) + dirname + std::string( "\"" ) + ); + return( count ); +} + // ------------------------------------------------------------------------- void cpPlugins::Interface:: UnloadAll( ) @@ -146,13 +197,16 @@ UnloadAll( ) cpPlugins::ProcessObject::Pointer cpPlugins::Interface:: Create( const std::string& category, const std::string& name ) { - cpPlugins::ProcessObject::Pointer filter = NULL; + typedef cpPlugins::ProcessObject::Pointer _TPointer; + _TPointer filter = NULL; auto catIt = this->m_DynFilters.find( category ); if( catIt != this->m_DynFilters.end( ) ) { auto clsIt = catIt->second.find( name ); if( clsIt != catIt->second.end( ) ) - filter = clsIt->second.second( ); + filter = + ( reinterpret_cast< _TPointer* >( clsIt->second.second( ) ) )-> + GetPointer( ); } // fi return( filter ); @@ -177,29 +231,40 @@ cpPlugins::Interface:: TFilters cpPlugins::Interface:: _DLGetFilters( void* hnd ) { - typedef const TFilters ( *f_t )( ); - - TFilters filters; + // Get descriptors + typedef const char* ( *f_t )( ); + f_t f = NULL; #ifdef cpPlugins_SYS_WINDOWS - auto f = ( f_t )( - ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" ) - ); - std::cout << f << std::endl; + f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" ) ); #else // cpPlugins_SYS_WINDOWS - auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" ); - const char* err = dlerror( ); - if( err != NULL ) + f = ( f_t )( dlsym( hnd, "cpPlugins_LoadedFilters" ) ); +#endif // cpPlugins_SYS_WINDOWS + if( f == NULL ) { - dlclose( hnd ); + Self::_DLClose( hnd ); throw std::runtime_error( - std::string( - "cpPlugins::Interface: Library not recognized as a cpPlugins library: " - ) + std::string( err ) + "cpPlugins::Interface: Library not recognized as a cpPlugins library: " ); } // fi -#endif // cpPlugins_SYS_WINDOWS - filters = f( ); + std::string descriptors = f( ); + + // Demangle descriptors + TFilters filters; + std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' ); + std::istringstream str( descriptors ); + while( str ) + { + std::string value, category, name; + str >> value; + if( value == "" ) + continue; + std::replace( value.begin( ), value.end( ), ':', ' ' ); + std::istringstream value_str( value ); + value_str >> category >> name; + filters[ category ].insert( name ); + + } // elihw return( filters ); } @@ -213,16 +278,16 @@ _DLGetCreator( TCreator c = NULL; std::string func_name = category + "_" + name; #ifdef cpPlugins_SYS_WINDOWS - // TODO: + c = ( TCreator )( ::GetProcAddress( ( HMODULE )hnd, func_name.c_str( ) ) ); #else // cpPlugins_SYS_WINDOWS - c = ( TCreator )dlsym( hnd, func_name.c_str( ) ); + c = ( TCreator )( dlsym( hnd, func_name.c_str( ) ) ); +#endif // cpPlugins_SYS_WINDOWS if( c == NULL ) throw std::runtime_error( std::string( "cpPlugins::Interface: Class \"" ) + category + std::string( ":" ) + name + std::string( "\" does not have a valid creator function." ) ); -#endif // cpPlugins_SYS_WINDOWS return( c ); }