cgma
CubitDynamicLoader.cpp
Go to the documentation of this file.
00001 
00002 // We have 4 different implementations here
00003 // Windows, Unix, , HP-UX
00004 
00005 #include "CubitDynamicLoader.hpp"
00006 
00007 #include <vector>
00008 #include <sys/stat.h>
00009 
00010 #include "CubitMessage.hpp"
00011 #include "CubitString.hpp"
00012 
00013 static std::vector<CubitString> gSearchPaths;
00014 
00015 void CubitDynamicLoader::add_search_path(const char* path)
00016 {
00017   gSearchPaths.push_back(CubitString(path));
00018 }
00019 
00020 static bool absolute_path(const char* path)
00021 {
00022 #ifdef _WIN32
00023   // either a '\' or a 'x:' drive letter means absolute path
00024   return path[0] == '\\' || (path[0] != '\0') ? (path[1] == ':') : 0;
00025 #else
00026   // a '/' is always an absolute path
00027   return path[0] == '/';
00028 #endif
00029 }
00030 
00031 CubitBoolean CubitDynamicLoader::library_exists(const char* library)
00032 {
00033   struct stat buf;
00034 
00035   // if absolute path, test it directly
00036   if(absolute_path(library))
00037   {
00038     return stat(library, &buf) == 0 ? CUBIT_TRUE : CUBIT_FALSE;
00039   }
00040   else
00041   { 
00042     // try finding with our search paths
00043     for(int i=0; i<(int)gSearchPaths.size(); i++)
00044     {
00045       CubitString path = gSearchPaths[i] + CubitString("/") + library;
00046       if(stat(path.c_str(), &buf) == 0)
00047         return CUBIT_TRUE;
00048     }
00049   }
00050   
00051   // one more final attempt
00052   if (stat(library, &buf) == 0)
00053     return CUBIT_TRUE;
00054 
00055   return CUBIT_FALSE;
00056 }
00057 
00058 #ifdef _WIN32
00059 
00060 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::InvalidLibraryHandle = NULL;
00061 
00062 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::load_library(const char* lib)
00063 {
00064   // disable message boxes about failure to find dlls
00065   //UINT old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
00066     UINT old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
00067 
00068   LibraryHandle handle = InvalidLibraryHandle;
00069   
00070   // if absolute path, test it directly
00071   if(absolute_path(lib))
00072   {
00073     handle = LoadLibraryW(CubitString::toUtf16(lib).c_str());
00074   }
00075   else
00076   { 
00077     // try finding with our search paths
00078     for(unsigned int i=0; i<gSearchPaths.size(); i++)
00079     {
00080       CubitString path = gSearchPaths[i]+CubitString("\\")+lib;
00081       handle = LoadLibraryW(CubitString::toUtf16(path.c_str()).c_str());
00082       if(handle != InvalidLibraryHandle)
00083       {
00084         SetErrorMode(old_error_mode);
00085         return handle;
00086       }
00087     }
00088   }
00089   
00090   // one more final attempt
00091   handle = LoadLibraryW(CubitString::toUtf16(lib).c_str());
00092 
00093   SetErrorMode(old_error_mode);
00094 
00095   return handle;
00096 }
00097 
00098 CubitString CubitDynamicLoader::get_error()
00099 {
00100   LPWSTR lpMsgBuf = NULL;
00101   DWORD dw = GetLastError(); 
00102 
00103   FormatMessageW(
00104     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00105     FORMAT_MESSAGE_FROM_SYSTEM |
00106     FORMAT_MESSAGE_IGNORE_INSERTS,
00107     NULL,
00108     dw,
00109     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00110     lpMsgBuf,
00111     0, NULL );
00112 
00113   CubitString error = CubitString::toUtf8(lpMsgBuf);
00114   LocalFree(lpMsgBuf);
00115 
00116   return error;
00117 }
00118 
00119 CubitStatus CubitDynamicLoader::unload_library(CubitDynamicLoader::LibraryHandle lib)
00120 {
00121   return FreeLibrary(lib) == FALSE ? CUBIT_FAILURE : CUBIT_SUCCESS;
00122 }
00123 
00124 void* CubitDynamicLoader::get_symbol_address(CubitDynamicLoader::LibraryHandle lib, const char* symbol)
00125 {
00126   return reinterpret_cast<void*>(GetProcAddress(lib, symbol));
00127 }
00128 
00129 const char* CubitDynamicLoader::library_prefix()
00130 {
00131   return "";
00132 }
00133 
00134 const char* CubitDynamicLoader::library_extension()
00135 {
00136   return ".dll";
00137 }
00138 
00139 #elif defined(__hpux)
00140 
00141 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::InvalidLibraryHandle = NULL;
00142 
00143 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::load_library(const char* lib)
00144 {
00145   LibraryHandle handle = InvalidLibraryHandle;
00146   
00147   // if absolute path, test it directly
00148   if(absolute_path(lib))
00149   {
00150     handle = shl_load(lib, BIND_DEFERRED | DYNAMIC_PATH | BIND_NONFATAL, 0L);
00151   }
00152   else
00153   { 
00154     // try finding with our search paths
00155     for(int i=0; i<gSearchPaths.size(); i++)
00156     {
00157       CubitString path = gSearchPaths[i]+CubitString("/")+lib;
00158       handle = shl_load(path.c_str(), BIND_DEFERRED | DYNAMIC_PATH | BIND_NONFATAL, 0L);
00159       if(handle != InvalidLibraryHandle)
00160         return handle;
00161     }
00162   }
00163   
00164   // one more final attempt
00165   handle = shl_load(lib, BIND_DEFERRED | DYNAMIC_PATH | BIND_NONFATAL, 0L);
00166   return handle;
00167 }
00168 
00169 CubitString CubitDynamicLoader::get_error()
00170 {
00171   return CubitString();
00172 }
00173 
00174 CubitStatus CubitDynamicLoader::unload_library(CubitDynamicLoader::LibraryHandle lib)
00175 {
00176   return shl_unload(lib) == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
00177 }
00178 
00179 void* CubitDynamicLoader::get_symbol_address(CubitDynamicLoader::LibraryHandle lib, const char* symbol)
00180 {
00181   void* address;
00182   return shl_findsym(&lib, symbol, TYPE_PROCEDURE, &address) < 0 ? NULL : address;
00183 }
00184 
00185 const char* CubitDynamicLoader::library_prefix()
00186 {
00187   return "lib";
00188 }
00189 
00190 const char* CubitDynamicLoader::library_extension()
00191 {
00192   return ".sl";
00193 }
00194 
00195 #else
00196 
00197 #include <dlfcn.h>
00198 
00199 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::InvalidLibraryHandle = NULL;
00200 
00201 CubitDynamicLoader::LibraryHandle CubitDynamicLoader::load_library(const char* lib)
00202 {
00203   // if absolute path, test it directly
00204   if(absolute_path(lib))
00205   {
00206     return dlopen(lib, RTLD_LAZY);
00207   }
00208   else
00209   { 
00210     // try finding with our search paths
00211     for(int i=0; i<(int)gSearchPaths.size(); i++)
00212     {
00213       CubitString path = gSearchPaths[i]+CubitString("/")+lib;
00214       LibraryHandle handle = dlopen(path.c_str(), RTLD_LAZY);
00215       if(handle != InvalidLibraryHandle)
00216         return handle;
00217     }
00218   }
00219   
00220   // one more final attempt
00221   return dlopen(lib, RTLD_LAZY );
00222 }
00223 
00224 CubitString CubitDynamicLoader::get_error()
00225 {
00226   return dlerror();
00227 }
00228 
00229 CubitStatus CubitDynamicLoader::unload_library(CubitDynamicLoader::LibraryHandle lib)
00230 {
00231   return dlclose(lib) == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
00232 }
00233 
00234 void* CubitDynamicLoader::get_symbol_address(CubitDynamicLoader::LibraryHandle lib, const char* symbol)
00235 {
00236   return dlsym(lib, symbol);
00237 }
00238 
00239 const char* CubitDynamicLoader::library_prefix()
00240 {
00241   return "lib";
00242 }
00243 
00244 const char* CubitDynamicLoader::library_extension()
00245 {
00246   return ".so";
00247 }
00248 #endif
00249 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines