cgma
|
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