1 #include <cpPlugins/Interface.h>
3 #ifdef cpPlugins_SYS_WINDOWS
4 #else // cpPlugins_SYS_WINDOWS
6 #endif // cpPlugins_SYS_WINDOWS
8 // -------------------------------------------------------------------------
14 // -------------------------------------------------------------------------
15 cpPlugins::Interface::
21 // -------------------------------------------------------------------------
22 const cpPlugins::Interface::
23 TFilters& cpPlugins::Interface::
26 return( this->m_Filters );
29 // -------------------------------------------------------------------------
30 void cpPlugins::Interface::
31 LoadPluginFile( const std::string& filename )
33 // Open library with its canonical path name
34 auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
35 void* hnd = Self::_DLOpen( canonical_fn );
37 throw std::runtime_error(
38 std::string( "cpPlugins::Interface: Could not load library \"" ) +
44 TFilters filters = Self::_DLGetFilters( hnd );
46 // Save the loaded filters info
47 bool save_handler = false;
48 for( auto catIt = filters.begin( ); catIt != filters.end( ); ++catIt )
50 // Check if the filter is completely new
51 auto act_catIt = this->m_Filters.find( catIt->first );
53 auto clsIt = catIt->second.begin( );
54 clsIt != catIt->second.end( );
58 bool new_filter = true;
59 if( act_catIt != this->m_Filters.end( ) )
61 ( act_catIt->second.find( *clsIt ) == act_catIt->second.end( ) );
66 // Update filters container
67 TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
70 this->m_DynFilters[ catIt->first][ *clsIt ] =
71 TDynFunc( canonical_fn, creator );
72 this->m_Filters[ catIt->first ].insert( *clsIt );
83 // Keep dynlib handler, if needed
85 this->m_DynLibraries[ canonical_fn ] = hnd;
87 Self::_DLClose( hnd );
90 // -------------------------------------------------------------------------
91 void cpPlugins::Interface::
95 auto d = this->m_DynLibraries.begin( );
96 d != this->m_DynLibraries.end( );
99 Self::_DLClose( d->second );
100 this->m_DynLibraries.clear( );
101 this->m_DynFilters.clear( );
102 this->m_Filters.clear( );
105 // -------------------------------------------------------------------------
106 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
107 Create( const std::string& category, const std::string& name )
109 cpPlugins::ProcessObject::Pointer filter = NULL;
110 auto catIt = this->m_DynFilters.find( category );
111 if( catIt != this->m_DynFilters.end( ) )
113 auto clsIt = catIt->second.find( name );
114 if( clsIt != catIt->second.end( ) )
115 filter = clsIt->second.second( );
121 // -------------------------------------------------------------------------
122 void* cpPlugins::Interface::
123 _DLOpen( const std::string& fname )
126 #ifdef cpPlugins_SYS_WINDOWS
128 #else // cpPlugins_SYS_WINDOWS
129 hnd = dlopen( fname.c_str( ), RTLD_NOW | RTLD_GLOBAL );
131 #endif // cpPlugins_SYS_WINDOWS
135 // -------------------------------------------------------------------------
136 cpPlugins::Interface::
137 TFilters cpPlugins::Interface::
138 _DLGetFilters( void* hnd )
141 #ifdef cpPlugins_SYS_WINDOWS
143 #else // cpPlugins_SYS_WINDOWS
144 typedef const TFilters ( *f_t )( );
145 auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" );
146 const char* err = dlerror( );
150 throw std::runtime_error(
152 "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
153 ) + std::string( err )
158 #endif // cpPlugins_SYS_WINDOWS
162 // -------------------------------------------------------------------------
163 cpPlugins::Interface::
164 TCreator cpPlugins::Interface::
166 void* hnd, const std::string& category, const std::string& name
170 std::string func_name = category + "_" + name;
171 #ifdef cpPlugins_SYS_WINDOWS
173 #else // cpPlugins_SYS_WINDOWS
174 c = ( TCreator )dlsym( hnd, func_name.c_str( ) );
176 throw std::runtime_error(
177 std::string( "cpPlugins::Interface: Class \"" ) +
178 category + std::string( ":" ) + name +
179 std::string( "\" does not have a valid creator function." )
181 #endif // cpPlugins_SYS_WINDOWS
185 // -------------------------------------------------------------------------
186 void cpPlugins::Interface::
187 _DLClose( void* hnd )
189 #ifdef cpPlugins_SYS_WINDOWS
191 #else // cpPlugins_SYS_WINDOWS
193 #endif // cpPlugins_SYS_WINDOWS