//-- FILE: plugin.h
//-- CODER: KUBO Takuya (kubo@ees.hokudai.ac.jp)
//--
//-- (C)opyright 2000 KUBO Takuya (kubo@ees.hokudai.ac.jp).
//-- All rights are reserved.
//-- Do not modify without amending copyright,
//-- distribute freely but retain this paragraph.
//--
//-- CHANGE: Thu Aug 31 20:33:35 2000
#if !defined(___Class_PLUGIN)
#define ___Class_PLUGIN
#include <string>
#include <dlfcn.h> // dlopen, dlsym, dlclose
#include <unistd.h> // unlink
using namespace std;
template <class ReturnType, class ParamType, class DataType>
class Plugin
{
private:
ReturnType ( *plugin_function )( ParamType&, DataType& );
void* DLSym( void*, const string&, const string& );
void* handle;
public:
Plugin( const string&, const string& );
~Plugin( void ) { dlclose( handle ); };
ReturnType Val( ParamType& param, DataType& data ) {
return ( *plugin_function )( param, data );
}
};
// Constructor
template <class ReturnType, class ParamType, class DataType>
Plugin<ReturnType, ParamType, DataType>::Plugin(
const string& plugin_function_so,
const string& function_namekey
) :
handle( NULL )
{
// dlopen
handle = dlopen( plugin_function_so.c_str(), RTLD_LAZY );
if ( !handle ) {
cerr << dlerror() << endl;
exit( 1 );
}
plugin_function = ( ReturnType ( * )( ParamType&, DataType& ) )
DLSym( handle, plugin_function_so, function_namekey );
}
// DLSym : return void*
template <class ReturnType, class ParamType, class DataType>
void* Plugin<ReturnType, ParamType, DataType>::DLSym(
void* handle,
const string& plugin_function_so,
const string& function_namekey
) {
// nm plugin_function_so | grep 'T function' > tmp_file
string tmp_file( "./tmp_tmp_tmp_file" );
string command( "nm " );
command += plugin_function_so;
command += " | grep 'T " + function_namekey + "' > " + tmp_file;
system( command.c_str() );
// A sample of 'nm | grep function' line
// 000026e0 T function__FR10ParametersRt6vector2ZdZt9allocator1Zd
// Reading tmp_file and get f_name
ifstream input_stream;
input_stream.open( tmp_file.c_str(), ios::in );
string f_name, dummy;
input_stream >> dummy >> dummy >> f_name;
input_stream.close();
unlink( tmp_file.c_str() ); // remove tmp_file
// dlsym
void* pointer_to_function( dlsym( handle, f_name.c_str() ) );
char* error( dlerror() );
if ( error != NULL ) {
cerr << error << endl;
exit( 1 );
}
return pointer_to_function;
}
#endif