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