Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArModuleLoader.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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     //dlclose(handle);
00142     //return(STATUS_INVALID);
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       //ArLog::log(ArLog::Terse, "Failure to find module exit function: '%s'",
00219       //dlerror());
00220       //ret=STATUS_INVALID;
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   //for (iter=ourModMap.begin(); iter != ourModMap.end(); iter=ourModMap.begin())
00248 
00249 }

Generated on Tue Feb 20 10:51:40 2007 for Aria by  doxygen 1.4.0