1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
#include <kore/kore.h>
#include <kore/version.h>
#include <kore/pluginloader.h>
#include <kore/plugin.h>
#if defined( KORE_WIN32 )
#elif defined( KORE_BEOS )
#include <image.h>
#elif defined( KORE_ATHEOS )
#include <atheos/image.h>
#else
#include <dlfcn.h>
#endif
#define PLDR_MAJOR 0
#define PLDR_MINOR 0
#define PLDR_REVISION 1
#define PLDR_VERSION "0.0.1"
#define PLDR_API_MAJOR 0
#define PLDR_API_MINOR 0
#define PLDR_API_REVISION 1
#define PLDR_API_VERSION "0.0.1"
#define PLDR_NAME "Plugin Loader"
#define PLDR_TYPE "Plugin Loader"
#define PLDR_DESCRIPTION "Default Kore Plugin Loader"
#define PLDR_SERVICE "Kore/Kernel/Plugin Loader"
#define PLDR_SERVICE_DESCRIPTION "Kore Plugin Loader"
using namespace kore;
PluginLoader::PluginLoader()
{
_loaderVersion = new Version(PLDR_MAJOR,PLDR_MINOR,PLDR_REVISION,PLDR_VERSION);
_loaderAPIVersion = new Version(PLDR_API_MAJOR,PLDR_API_MINOR,PLDR_API_REVISION,PLDR_API_VERSION);
_loaderInfo = new Info(this, PLDR_NAME, PLDR_TYPE, PLDR_DESCRIPTION, _loaderVersion, _loaderAPIVersion);
setInfo(_loaderInfo);
_loaderService = new Service(this, PLDR_SERVICE, PLDR_SERVICE_DESCRIPTION);
addService(_loaderService);
}
PluginLoader::~PluginLoader()
{
delete _loaderInfo;
delete _loaderVersion;
delete _loaderAPIVersion;
delete _loaderService;
}
// "my_plugin" -> "libmy_plugin.so"/"my_plugin.dll"
char* PluginLoader::libName2fileName(const char* libName)
{
int n = strlen(libName);
#ifdef KORE_WIN32
char* fn = new char[n+1+4];
return strcat(strcpy(fn,libName),".dll");
#else
char* fn = new char[n+1+6];
return strcat(strcat(strcpy(fn,"lib"),libName),".so");
#endif
}
// "libmy_plugin.so"/"my_plugin.dll" -> "my_plugin"
char* PluginLoader::fileName2libName(const char* fileName)
{
#ifdef KORE_WIN32
int n = strlen(libName) - 4;
char* ln = new char[n+1];
#else
char* pos = strstr(fileName, ".so");
int n = pos - fileName - 3;
char* ln = new char[n+1];
fileName += 3;
#endif
return strncpy(ln, fileName, n);
}
Plugin* PluginLoader::runPlugin(const char* libName, const char* libPath, int libFlags)
{
Plugin* plugin = openPlugin(libName, libPath, libFlags);
if( plugin )
plugin->initPlugin();
return plugin;
}
Plugin* PluginLoader::openPlugin(const char* libName, const char* libPath, int libFlags)
{
HMODULE handle;
char* fileName = libName2fileName(libName);
char* filePath = 0;
Plugin* res;
if( libPath && libPath[0] )
{
int n = strlen(libPath);
int slash = libPath[n-1] == '/' ? 0 : 1;
filePath = new char[n+strlen(fileName)+slash+1];
strcpy(filePath, libPath);
if( slash )
{
filePath[n] = '/';
filePath[n+1] = 0;
}
}
else
{
filePath = new char[strlen(fileName)+1];
filePath[0] = 0;
}
strcat( filePath, fileName );
//cout << "Loading: " << filePath << endl;
delete[] fileName;
#if defined( KORE_WIN32 )
handle = LoadLibrary(filePath);
#elif defined( KORE_BEOS )
handle = load_add_on(filePath);
#elif defined( KORE_ATHEOS )
handle = load_library( filePath, 0 );
#else
handle = dlopen(filePath, libFlags | RTLD_NOW );
#endif
delete[] filePath;
//cout << "Loaded: " << handle << endl;
#if defined( KORE_BEOS )
if( handle < B_NO_ERROR )
#elif defined( KORE_ATHEOS )
if( handle < 0 )
#else
if( !handle )
#endif
return 0;
//cout << "Found: " << handle << endl;
PluginFuncType sym = 0;
#if defined( KORE_WIN32 )
sym = (PluginFuncType) GetProcAddress( handle, "plugin" );
#elif defined( KORE_BEOS )
if( B_OK != get_image_symbol( handle, "plugin", B_SYMBOL_TYPE_TEXT, reinterpret_cast<void**>(&sym) ) )
sym = 0;
#elif defined( KORE_ATHEOS )
if( 0 != get_symbol_address( handle, "plugin", -1, reinterpret_cast<void**>(&sym) ) )
sym = 0;
#else
sym = (PluginFuncType) dlsym( const_cast<void*>(handle), "plugin" );
#endif
//cout << "Done: " << sym << endl;
if( !sym )
res = new Plugin(handle,libName,libPath,libFlags);
else
res = sym(handle,libName,libPath,libFlags);
//cout << "Called: " << sym << endl;
res->pluginLoaded();
return res;
}
void PluginLoader::closePlugin(Plugin* plugin)
{
plugin->unloadingPlugin();
#if defined( KORE_WIN32 )
FreeLibrary( plugin->libHandle() );
#elif defined( KORE_BEOS )
unload_add_on( plugin->libHandle() );
#elif defined( KORE_ATHEOS )
unload_library( plugin->libHandle() );
#else
dlclose(const_cast<void*> (plugin->libHandle()));
#endif
}
const char* PluginLoader::lastError()
{
_lastError[0]=0;
#if defined( KORE_WIN32 )
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), _lastError, 100, NULL );
#elif defined( KORE_BEOS )
strncpy(_lastError, strerror(errno), 100);
#elif defined( KORE_ATHEOS )
strncpy(_lastError, strerror(errno), 100);
#else
strncpy(_lastError, dlerror(), 100);
#endif
return _lastError;
}
|