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