Commit c6655068 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - it is now possible to have one shared lib providing multiple...

[CHANGE] - it is now possible to have one shared lib providing multiple modules. No changes for existing modules needed.
parent 90e3052b
......@@ -596,18 +596,29 @@ private:
t_ModuleErrorSignalType signal_error;
};
/**
* Simply a list of modules. The type is used by the following macros and typedefs
*/
typedef std::vector< boost::shared_ptr< WModule > > WModuleList;
/**
* The signature used for the module loading entry point
*/
typedef void ( *W_LOADABLE_MODULE_SIGNATURE )( WModuleList& );
/**
* The following macro is used by modules so the factory can acquire a prototype instance from a shared library using the symbol.
* You can write this symbol for your own if you need to add multiple modules to the list. This one is for convenience.
*
* \note we need the module instance to be created using a shared_ptr as WModule is derived from enable_shared_from_this. Removing the shared
* pointer causes segmentation faults during load.
*/
#ifdef _MSC_VER
#define W_LOADABLE_MODULE( MODULECLASS ) \
extern "C" __declspec(dllexport) void WLoadModule( boost::shared_ptr< WModule > &m ) { m = boost::shared_ptr< WModule >( new MODULECLASS ); } // NOLINT
extern "C" __declspec(dllexport) void WLoadModule( WModuleList& m ) { m.push_back( boost::shared_ptr< WModule >( new MODULECLASS ) ); } // NOLINT
#else
#define W_LOADABLE_MODULE( MODULECLASS ) \
extern "C" void WLoadModule( boost::shared_ptr< WModule > &m ) { m = boost::shared_ptr< WModule >( new MODULECLASS ); } // NOLINT
extern "C" void WLoadModule( WModuleList& m ) { m.push_back( boost::shared_ptr< WModule >( new MODULECLASS ) ); } // NOLINT
#endif
/**
......
......@@ -64,28 +64,31 @@ void WModuleLoader::load( WSharedAssociativeContainer< std::set< boost::shared_p
WSharedLib l( i->path() );
// get instantiation function
typedef void ( *createInstanceFunc )( boost::shared_ptr< WModule > & );
createInstanceFunc f;
l.fetchFunction< createInstanceFunc >( W_LOADABLE_MODULE_SYMBOL, f );
W_LOADABLE_MODULE_SIGNATURE f;
l.fetchFunction< W_LOADABLE_MODULE_SIGNATURE >( W_LOADABLE_MODULE_SYMBOL, f );
// get the first prototype
boost::shared_ptr< WModule > m;
WModuleList m;
f( m );
// could the prototype be created?
if( !m )
if( m.empty() )
{
WLogger::getLogger()->addLogMessage( "Load failed for module \"" + i->path().file_string() + "\". Could not create " +
WLogger::getLogger()->addLogMessage( "Load failed for module \"" + i->path().file_string() + "\". Could not create any " +
"prototype instance.", "Module Loader", LL_ERROR );
continue;
}
else
{
// yes, add it to the list of prototypes
WLogger::getLogger()->addLogMessage( "Loaded " + i->path().file_string(), "Module Loader", LL_INFO );
m->setLocalPath( i->path().parent_path() );
ticket->get().insert( m );
m_libs.push_back( l );
for ( WModuleList::const_iterator iter = m.begin(); iter != m.end(); ++iter )
{
( *iter )->setLocalPath( i->path().parent_path() );
ticket->get().insert( *iter );
m_libs.push_back( l );
}
wlog::info( "Module Loader" ) << "Loaded " << m.size() << " modules from " << i->path().file_string();
}
// lib gets closed if l looses focus
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment