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