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