1 #include <cpPlugins/Interface.h>
3 #ifdef cpPlugins_SYS_WINDOWS
5 #else // cpPlugins_SYS_WINDOWS
7 #endif // cpPlugins_SYS_WINDOWS
9 // -------------------------------------------------------------------------
10 cpPlugins::Interface::
15 // -------------------------------------------------------------------------
16 cpPlugins::Interface::
22 // -------------------------------------------------------------------------
23 const cpPlugins::Interface::
24 TFilters& cpPlugins::Interface::
27 return( this->m_Filters );
30 // -------------------------------------------------------------------------
31 bool cpPlugins::Interface::
32 LoadConfiguration( const std::string& filename )
34 std::ifstream in( filename.c_str( ) );
40 while( std::getline( in, line ) )
44 this->LoadPluginFile( line );
56 // -------------------------------------------------------------------------
57 bool cpPlugins::Interface::
58 SaveConfiguration( const std::string& filename ) const
60 std::ofstream out( filename.c_str( ) );
63 auto dIt = this->m_DynLibraries.begin( );
64 for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
65 out << dIt->first << std::endl;
69 // -------------------------------------------------------------------------
70 void cpPlugins::Interface::
71 LoadPluginFile( const std::string& filename )
73 // Open library with its canonical path name
74 auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
75 void* hnd = Self::_DLOpen( canonical_fn );
77 throw std::runtime_error(
78 std::string( "cpPlugins::Interface: Could not load library \"" ) +
84 TFilters filters = Self::_DLGetFilters( hnd );
86 // Save the loaded filters info
87 bool save_handler = false;
88 for( auto catIt = filters.begin( ); catIt != filters.end( ); ++catIt )
90 // Check if the filter is completely new
91 auto act_catIt = this->m_Filters.find( catIt->first );
93 auto clsIt = catIt->second.begin( );
94 clsIt != catIt->second.end( );
98 bool new_filter = true;
99 if( act_catIt != this->m_Filters.end( ) )
101 ( act_catIt->second.find( *clsIt ) == act_catIt->second.end( ) );
106 // Update filters container
107 TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
108 if( creator != NULL )
110 this->m_DynFilters[ catIt->first][ *clsIt ] =
111 TDynFunc( canonical_fn, creator );
112 this->m_Filters[ catIt->first ].insert( *clsIt );
123 // Keep dynlib handler, if needed
125 this->m_DynLibraries[ canonical_fn ] = hnd;
127 Self::_DLClose( hnd );
130 // -------------------------------------------------------------------------
131 void cpPlugins::Interface::
135 auto d = this->m_DynLibraries.begin( );
136 d != this->m_DynLibraries.end( );
139 Self::_DLClose( d->second );
140 this->m_DynLibraries.clear( );
141 this->m_DynFilters.clear( );
142 this->m_Filters.clear( );
145 // -------------------------------------------------------------------------
146 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
147 Create( const std::string& category, const std::string& name )
149 cpPlugins::ProcessObject::Pointer filter = NULL;
150 auto catIt = this->m_DynFilters.find( category );
151 if( catIt != this->m_DynFilters.end( ) )
153 auto clsIt = catIt->second.find( name );
154 if( clsIt != catIt->second.end( ) )
155 filter = clsIt->second.second( );
161 // -------------------------------------------------------------------------
162 void* cpPlugins::Interface::
163 _DLOpen( const std::string& fname )
166 #ifdef cpPlugins_SYS_WINDOWS
167 hnd = ::LoadLibraryA( fname.c_str( ) );
168 #else // cpPlugins_SYS_WINDOWS
169 hnd = dlopen( fname.c_str( ), RTLD_NOW | RTLD_GLOBAL );
171 #endif // cpPlugins_SYS_WINDOWS
175 // -------------------------------------------------------------------------
176 cpPlugins::Interface::
177 TFilters cpPlugins::Interface::
178 _DLGetFilters( void* hnd )
180 typedef const TFilters ( *f_t )( );
183 #ifdef cpPlugins_SYS_WINDOWS
185 ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" )
187 std::cout << f << std::endl;
188 #else // cpPlugins_SYS_WINDOWS
189 auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" );
190 const char* err = dlerror( );
194 throw std::runtime_error(
196 "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
197 ) + std::string( err )
201 #endif // cpPlugins_SYS_WINDOWS
206 // -------------------------------------------------------------------------
207 cpPlugins::Interface::
208 TCreator cpPlugins::Interface::
210 void* hnd, const std::string& category, const std::string& name
214 std::string func_name = category + "_" + name;
215 #ifdef cpPlugins_SYS_WINDOWS
217 #else // cpPlugins_SYS_WINDOWS
218 c = ( TCreator )dlsym( hnd, func_name.c_str( ) );
220 throw std::runtime_error(
221 std::string( "cpPlugins::Interface: Class \"" ) +
222 category + std::string( ":" ) + name +
223 std::string( "\" does not have a valid creator function." )
225 #endif // cpPlugins_SYS_WINDOWS
229 // -------------------------------------------------------------------------
230 void cpPlugins::Interface::
231 _DLClose( void* hnd )
233 #ifdef cpPlugins_SYS_WINDOWS
234 ::FreeLibrary( ( HMODULE )hnd );
235 #else // cpPlugins_SYS_WINDOWS
237 #endif // cpPlugins_SYS_WINDOWS