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