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