00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <dlfcn.h>
00027
00028 #include <QFile>
00029
00030 #include "plugin.h"
00031 #include "mytools.h"
00032 #include "debug.h"
00033
00034 PluginCreator::~PluginCreator()
00035 {
00036 dlclose(mLibraryHandle);
00037 }
00038
00039 Plugin* PluginCreator::createPlugin(std::string args)
00040 {
00041 Plugin* plugin = (*mCreatePluginFctn)();
00042 if (!plugin) return NULL;
00043 if (plugin->init(0,NULL) != SUCCESS) {
00044 DBGA("Failed to initialize new plugin of type " << mType);
00045 delete plugin;
00046 return NULL;
00047 }
00048 return plugin;
00049 }
00050
00051 PluginCreator* PluginCreator::loadFromLibrary(std::string libName)
00052 {
00053 QString filename = QString::fromStdString(libName);
00054
00055 if (!filename.endsWith(".so")) {
00056 filename.append(".so");
00057 }
00058
00059 if (filename.startsWith("/")) {
00060
00061 QFile file(filename);
00062 if (!file.exists()) {
00063 DBGA("Could not find absolute plugin file " << filename.latin1());
00064 return NULL;
00065 }
00066 } else{
00067
00068 QString pluginDirs = QString(getenv("GRASPIT_PLUGIN_DIR"));
00069 if (pluginDirs.isNull()) {
00070 DBGA("Relative plugin file specified, but GRASPIT_PLUGIN_DIR is not set");
00071 return NULL;
00072 }
00073 bool found = false;
00074 for (int i=0; i<=pluginDirs.count(":"); i++) {
00075 QString dir = pluginDirs.section(':',i,i);
00076 if (!dir.endsWith("/")) dir.append("/");
00077 dir.append(filename);
00078 QFile file(dir);
00079 if (file.exists()) {
00080 found = true;
00081 filename = dir;
00082 break;
00083 }
00084 }
00085 if (!found) {
00086 DBGA("Could not find relative plugin file " << filename.latin1() <<
00087 " in any directory specified in GRASPIT_PLUGIN_DIR");
00088 return NULL;
00089 }
00090 }
00091
00092
00093 void* handle = dlopen(filename.toAscii().constData(), RTLD_NOW | RTLD_GLOBAL);
00094 char *errstr = dlerror();
00095 if (!handle) {
00096 DBGA("Failed to open dynamic library " << filename.toAscii().constData() );
00097 if (errstr) DBGA("Error: " << errstr);
00098 return NULL;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 PluginCreator::CreatePluginFctn createPluginFctn;
00108 *(void **)(&createPluginFctn) = dlsym(handle,"createPlugin");
00109 if (dlerror()) {
00110 DBGA("Could not load symbol createPlugin from library " << filename.toAscii().constData());
00111 return NULL;
00112 }
00113
00114
00115 PluginCreator::GetTypeFctn getTypeFctn;
00116 *(void **)(&getTypeFctn) = dlsym(handle,"getType");
00117 if (dlerror()) {
00118 DBGA("Could not load symbol getType from library " << filename.toAscii().constData());
00119 return NULL;
00120 }
00121 std::string type = (*getTypeFctn)();
00122 if (type.empty()) {
00123 DBGA("Could not get plugin type from library " << filename.toAscii().constData());
00124 }
00125
00126
00127 bool autoStart = true;
00128 std::string defaultArgs;
00129 PluginCreator *creator = new PluginCreator(handle, createPluginFctn, autoStart, type, defaultArgs);
00130 return creator;
00131 }