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

ArModuleLoader.cpp

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

Generated on Wed Oct 19 12:56:36 2005 for Aria by  doxygen 1.4.0