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 "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #ifdef WIN32
00029 #else
00030 #include <dlfcn.h>
00031 #endif
00032 #include "ArModuleLoader.h"
00033 #include "ArModule.h"
00034 #include "ArLog.h"
00035
00036
00037 std::map<std::string, ArModuleLoader::DllRef> ArModuleLoader::ourModMap;
00038
00039
00040 #ifdef WIN32
00041
00042 #define RTLD_NOW 0
00043 #define RTLD_GLOBAL 0
00044
00045 HINSTANCE dlopen(const char *fileName, int flag)
00046 {
00047 return(LoadLibrary(fileName));
00048 }
00049
00050 int dlclose(HINSTANCE handle)
00051 {
00052 FreeLibrary(handle);
00053 return(0);
00054 }
00055
00056 void *dlsym(HINSTANCE handle, char *symbol)
00057 {
00058 return(GetProcAddress(handle, symbol));
00059 }
00060
00061 const char *dlerror(void)
00062 {
00063 return(0);
00064 }
00065 #endif // WIN32
00066
00067
00099 AREXPORT ArModuleLoader::Status ArModuleLoader::load(const char *modName,
00100 ArRobot *robot,
00101 void *modArgument,
00102 bool quiet)
00103 {
00104 std::string name;
00105 std::map<std::string, DllRef>::iterator iter;
00106 DllRef handle;
00107 bool (*func)(ArRobot*,void*);
00108 bool ret;
00109
00110 name=modName;
00111 #ifdef WIN32
00112 if (strstr(modName, ".dll") == 0)
00113 name+=".dll";
00114 #else
00115 if (strstr(modName, ".so") == 0)
00116 name+=".so";
00117 #endif
00118
00119 iter=ourModMap.find(name);
00120 if (iter != ourModMap.end())
00121 return(STATUS_ALREADY_LOADED);
00122
00123 handle=dlopen(name.c_str(), RTLD_NOW | RTLD_GLOBAL);
00124
00125 if (!handle || dlerror() != NULL)
00126 {
00127 if (!quiet)
00128 ArLog::log(ArLog::Terse, "Failure to load module '%s': %s",
00129 name.c_str(), dlerror());
00130 return(STATUS_FAILED_OPEN);
00131 }
00132
00133 func=(bool(*)(ArRobot*,void*))dlsym(handle, "ariaInitModule");
00134 if (!func || dlerror() != NULL)
00135 {
00136 if (!quiet)
00137 ArLog::log(ArLog::Terse, "No module initializer for %s.", modName);
00138 ourModMap.insert(std::map<std::string, DllRef>::value_type(name,
00139 handle));
00140 return(STATUS_SUCCESS);
00141
00142
00143 }
00144 ret=(*func)(robot, modArgument);
00145
00146 if (ret)
00147 {
00148 ourModMap.insert(std::map<std::string, DllRef>::value_type(name,
00149 handle));
00150 return(STATUS_SUCCESS);
00151 }
00152 else
00153 {
00154 if (!quiet)
00155 ArLog::log(ArLog::Terse, "Module '%s' failed its init sequence",
00156 name.c_str());
00157 dlclose(handle);
00158 return(STATUS_INIT_FAILED);
00159 }
00160 }
00161
00162
00168 AREXPORT ArModuleLoader::Status ArModuleLoader::reload(const char *modName,
00169 ArRobot *robot,
00170 void *modArgument,
00171 bool quiet)
00172 {
00173 close(modName, quiet);
00174 return(load(modName, robot, modArgument, quiet));
00175 }
00176
00183 AREXPORT ArModuleLoader::Status ArModuleLoader::close(const char *modName,
00184 bool quiet)
00185 {
00186 std::string name;
00187 std::map<std::string, DllRef>::iterator iter;
00188 bool (*func)();
00189 bool funcRet;
00190 DllRef handle;
00191 Status ret=STATUS_SUCCESS;
00192
00193 name=modName;
00194 #ifdef WIN32
00195 if (strstr(modName, ".dll") == 0)
00196 name+=".dll";
00197 #else
00198 if (strstr(modName, ".so") == 0)
00199 name+=".so";
00200 #endif
00201
00202 iter=ourModMap.find(name.c_str());
00203 if (iter == ourModMap.end())
00204 {
00205 ArLog::log(ArLog::Terse, "Module '%s' could not be found to be closed.",
00206 modName);
00207 return(STATUS_NOT_FOUND);
00208 }
00209 else
00210 {
00211 handle=(*iter).second;
00212 func=(bool(*)())dlsym(handle, "ariaExitModule");
00213 if (!func)
00214 {
00215 if (!quiet)
00216 ArLog::log(ArLog::Verbose,
00217 "Failure to find module exit function for '%s'", (*iter).first.c_str());
00218
00219
00220
00221 ourModMap.erase(name);
00222 return STATUS_SUCCESS;
00223 }
00224 funcRet=(*func)();
00225 if (funcRet)
00226 ret=STATUS_SUCCESS;
00227 else
00228 {
00229 if (!quiet)
00230 ArLog::log(ArLog::Terse, "Module '%s' failed its exit sequence",
00231 modName);
00232 ret=STATUS_INIT_FAILED;
00233 }
00234 dlclose(handle);
00235 ourModMap.erase(name);
00236 }
00237
00238 return(ret);
00239 }
00240
00241 AREXPORT void ArModuleLoader::closeAll()
00242 {
00243 std::map<std::string, DllRef>::iterator iter;
00244
00245 while ((iter = ourModMap.begin()) != ourModMap.end())
00246 close((*iter).first.c_str());
00247
00248
00249 }