1 #define PETSC_DLL 2 /* 3 Low-level routines for managing dynamic link libraries (DLLs). 4 */ 5 6 #include "petsc.h" 7 #include "petscfix.h" 8 9 /* XXX Should be done better !!!*/ 10 #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 11 #undef PETSC_HAVE_WINDOWS_H 12 #undef PETSC_HAVE_DLFCN_H 13 #endif 14 15 #if defined(PETSC_HAVE_WINDOWS_H) 16 #include <windows.h> 17 #elif defined(PETSC_HAVE_DLFCN_H) 18 #include <dlfcn.h> 19 #endif 20 21 /* XXX ----------------------------------- */ 22 /* Just for testing, REMOVE THIS when done */ 23 #if 0 24 #undef PETSC_HAVE_WINDOWS_H 25 #undef PETSC_HAVE_DLFCN_H 26 #elif 0 27 #undef PETSC_HAVE_DLFCN_H 28 #define PETSC_HAVE_WINDOWS_H 29 #define PETSC_HAVE_LOADLIBRARY 30 #define PETSC_HAVE_GETPROCADDRESS 31 #define PETSC_HAVE_FREELIBRARY 32 #define HMODULE int 33 extern HMODULE LoadLibrary(const char*); 34 extern int FreeLibrary(HMODULE); 35 extern HMODULE GetCurrentProcess(void); 36 extern void* GetProcAddress(HMODULE,const char*); 37 #endif 38 /* XXX ----------------------------------- */ 39 40 41 #if defined(PETSC_HAVE_WINDOWS_H) 42 typedef HMODULE dlhandle_t; 43 #elif defined(PETSC_HAVE_DLFCN_H) 44 typedef void* dlhandle_t; 45 #else 46 typedef void* dlhandle_t; 47 #endif 48 49 #undef __FUNCT__ 50 #define __FUNCT__ "PetscDLOpen" 51 /*@C 52 PetscDLOpen - 53 @*/ 54 PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 55 { 56 int dlflags1,dlflags2; 57 dlhandle_t dlhandle; 58 59 PetscFunctionBegin; 60 PetscValidCharPointer(name, 1); 61 PetscValidPointer(handle, 3); 62 63 dlflags1 = 0; 64 dlflags2 = 0; 65 dlhandle = (dlhandle_t) 0; 66 *handle = (PetscDLHandle) 0; 67 68 /* 69 --- LoadLibrary --- 70 */ 71 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 72 dlhandle = LoadLibrary(name); 73 if (!dlhandle) { 74 #if defined(PETSC_HAVE_GETLASTERROR) 75 PetscErrorCode ierr; 76 DWORD erc; 77 char *buff; 78 erc = GetLastError(); 79 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 80 NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 81 ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 82 "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 83 LocalFree(buff); 84 PetscFunctionReturn(ierr); 85 #else 86 SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 87 #endif 88 } 89 90 /* 91 --- dlopen --- 92 */ 93 #elif defined(PETSC_HAVE_DLFCN_H) 94 /* 95 Mode indicates symbols required by symbol loaded with dlsym() 96 are only loaded when required (not all together) also indicates 97 symbols required can be contained in other libraries also opened 98 with dlopen() 99 */ 100 #if defined(PETSC_HAVE_RTLD_LAZY) 101 dlflags1 = RTLD_LAZY; 102 #endif 103 #if defined(PETSC_HAVE_RTLD_NOW) 104 if (flags & PETSC_DL_NOW) 105 dlflags1 = RTLD_NOW; 106 #endif 107 #if defined(PETSC_HAVE_RTLD_LOCAL) 108 dlflags2 = RTLD_LOCAL; 109 #endif 110 #if defined(PETSC_HAVE_RTLD_GLOBAL) 111 if (flags & PETSC_DL_GLOBAL) 112 dlflags2 = RTLD_GLOBAL; 113 #endif 114 #if defined(PETSC_HAVE_DLERROR) 115 dlerror(); /* clear any previous error */ 116 #endif 117 dlhandle = dlopen(name,dlflags1|dlflags2); 118 if (!dlhandle) { 119 #if defined(PETSC_HAVE_DLERROR) 120 const char *errmsg = dlerror(); 121 #else 122 const char *errmsg = "unavailable"; 123 #endif 124 SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg) 125 } 126 127 /* 128 --- unimplemented --- 129 */ 130 #else 131 SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 132 #endif 133 134 *handle = (PetscDLHandle) dlhandle; 135 136 PetscFunctionReturn(0); 137 } 138 139 140 #undef __FUNCT__ 141 #define __FUNCT__ "PetscDLClose" 142 /*@C 143 PetscDLClose - 144 @*/ 145 PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 146 { 147 dlhandle_t dlhandle; 148 149 PetscFunctionBegin; 150 PetscValidPointer(handle,1); 151 152 dlhandle = (dlhandle_t) *handle; 153 154 /* 155 --- FreeLibrary --- 156 */ 157 #if defined(PETSC_HAVE_WINDOWS_H) 158 #if defined(PETSC_HAVE_FREELIBRARY) 159 if (FreeLibrary(dlhandle) == 0) { 160 #if defined(PETSC_HAVE_GETLASTERROR) 161 DWORD erc; 162 char *buff; 163 erc = GetLastError(); 164 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 165 NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 166 PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 167 LocalFree(buff); 168 #else 169 PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 170 #endif 171 } 172 #endif /* !PETSC_HAVE_FREELIBRARY */ 173 174 /* 175 --- dclose --- 176 */ 177 #elif defined(PETSC_HAVE_DLFCN_H) 178 #if defined(PETSC_HAVE_DLERROR) 179 dlerror(); /* clear any previous error */ 180 #endif 181 if (dlclose(dlhandle) < 0) { 182 #if defined(PETSC_HAVE_DLERROR) 183 const char *errmsg = dlerror(); 184 #else 185 const char *errmsg = "unavailable"; 186 #endif 187 PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 188 } 189 190 /* 191 --- unimplemented --- 192 */ 193 #else 194 SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 195 #endif 196 197 *handle = PETSC_NULL; 198 199 PetscFunctionReturn(0); 200 } 201 202 203 #undef __FUNCT__ 204 #define __FUNCT__ "PetscDLSym" 205 /*@C 206 PetscDLSym - 207 @*/ 208 PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 209 { 210 dlhandle_t dlhandle; 211 void *dlvalue; 212 213 PetscFunctionBegin; 214 PetscValidCharPointer(symbol,2); 215 PetscValidPointer(value,3); 216 217 dlhandle = (dlhandle_t) 0; 218 *value = 0; 219 220 /* 221 --- GetProcAddress --- 222 */ 223 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS) 224 if (handle != PETSC_NULL) 225 dlhandle = (dlhandle_t) handle; 226 else 227 dlhandle = (dlhandle_t) GetCurrentProcess(); 228 dlvalue = GetProcAddress(dlhandle,symbol); 229 230 /* 231 --- dlsym --- 232 */ 233 #elif defined(PETSC_HAVE_DLFCN_H) 234 if (handle != PETSC_NULL) 235 dlhandle = (dlhandle_t) handle; 236 else 237 dlhandle = (dlhandle_t) 0; 238 #if defined(PETSC_HAVE_DLERROR) 239 dlerror(); /* clear any previous error */ 240 #endif 241 dlvalue = dlsym(dlhandle,symbol); 242 #if defined(PETSC_HAVE_DLERROR) 243 if (!dlvalue) { /* dvalue could be actually NULL */ 244 const char *errmsg = dlerror(); 245 if (errmsg) { /* XXX Should we fail/inform about this? */ 246 #if 0 247 SETERRQ2(PETSC_ERR_FILE_UNEXPECTED,"Unable to load symbol %s\n Error message from dlsym() %s\n",symbol,errmsg); 248 #else 249 errmsg = 0; 250 #endif 251 } 252 } 253 #endif 254 255 /* 256 --- unimplemented --- 257 */ 258 #else 259 SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 260 #endif 261 262 *value = dlvalue; 263 264 PetscFunctionReturn(0); 265 } 266