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 done better !!!*/ 10*be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 11ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H 12ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 13ebd79076SLisandro Dalcin #endif 14ebd79076SLisandro Dalcin 15ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 16ebd79076SLisandro Dalcin #include <windows.h> 17*be1c6ad7SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 18ebd79076SLisandro Dalcin #include <dlfcn.h> 19ebd79076SLisandro Dalcin #endif 20ebd79076SLisandro Dalcin 21*be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */ 22*be1c6ad7SLisandro Dalcin /* Just for testing, REMOVE THIS when done */ 23ebd79076SLisandro Dalcin #if 0 24ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H 25ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 26ebd79076SLisandro Dalcin #elif 0 27ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 28ebd79076SLisandro Dalcin #define PETSC_HAVE_WINDOWS_H 29*be1c6ad7SLisandro Dalcin #define PETSC_HAVE_LOADLIBRARY 30ebd79076SLisandro Dalcin #define PETSC_HAVE_GETPROCADDRESS 31*be1c6ad7SLisandro Dalcin #define PETSC_HAVE_FREELIBRARY 32ebd79076SLisandro Dalcin #define HMODULE int 33ebd79076SLisandro Dalcin extern HMODULE LoadLibrary(const char*); 345673baf8SLisandro Dalcin extern int FreeLibrary(HMODULE); 35ebd79076SLisandro Dalcin extern HMODULE GetCurrentProcess(void); 36ebd79076SLisandro Dalcin extern void* GetProcAddress(HMODULE,const char*); 37ebd79076SLisandro Dalcin #endif 38*be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */ 39*be1c6ad7SLisandro Dalcin 40ebd79076SLisandro Dalcin 41ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 42ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t; 43ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 44ebd79076SLisandro Dalcin typedef void* dlhandle_t; 45ebd79076SLisandro Dalcin #else 46ebd79076SLisandro Dalcin typedef void* dlhandle_t; 47ebd79076SLisandro Dalcin #endif 48ebd79076SLisandro Dalcin 49ebd79076SLisandro Dalcin #undef __FUNCT__ 50ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen" 51ebd79076SLisandro Dalcin /*@C 52ebd79076SLisandro Dalcin PetscDLOpen - 53ebd79076SLisandro Dalcin @*/ 545673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 55ebd79076SLisandro Dalcin { 56*be1c6ad7SLisandro Dalcin int dlflags1,dlflags2; 57ebd79076SLisandro Dalcin dlhandle_t dlhandle; 58ebd79076SLisandro Dalcin 59ebd79076SLisandro Dalcin PetscFunctionBegin; 60ebd79076SLisandro Dalcin PetscValidCharPointer(name, 1); 61ebd79076SLisandro Dalcin PetscValidPointer(handle, 3); 62ebd79076SLisandro Dalcin 63*be1c6ad7SLisandro Dalcin dlflags1 = 0; 64*be1c6ad7SLisandro Dalcin dlflags2 = 0; 655673baf8SLisandro Dalcin dlhandle = (dlhandle_t) 0; 66*be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle) 0; 67ebd79076SLisandro Dalcin 685673baf8SLisandro Dalcin /* 695673baf8SLisandro Dalcin --- LoadLibrary --- 705673baf8SLisandro Dalcin */ 71*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 72*be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 73ebd79076SLisandro Dalcin if (!dlhandle) { 74ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 75ebd79076SLisandro Dalcin PetscErrorCode ierr; 76ebd79076SLisandro Dalcin DWORD erc; 77ebd79076SLisandro Dalcin char *buff; 78ebd79076SLisandro Dalcin erc = GetLastError(); 79ebd79076SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 80ebd79076SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 81ebd79076SLisandro Dalcin ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 82*be1c6ad7SLisandro Dalcin "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 83ebd79076SLisandro Dalcin LocalFree(buff); 84ebd79076SLisandro Dalcin PetscFunctionReturn(ierr); 85ebd79076SLisandro Dalcin #else 86*be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 87ebd79076SLisandro Dalcin #endif 88ebd79076SLisandro Dalcin } 895673baf8SLisandro Dalcin 905673baf8SLisandro Dalcin /* 915673baf8SLisandro Dalcin --- dlopen --- 925673baf8SLisandro Dalcin */ 93ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 94ebd79076SLisandro Dalcin /* 95ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 96ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 97ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 98ebd79076SLisandro Dalcin with dlopen() 99ebd79076SLisandro Dalcin */ 100*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 101*be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 102*be1c6ad7SLisandro Dalcin #endif 103ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 1045673baf8SLisandro Dalcin if (flags & PETSC_DL_NOW) 105*be1c6ad7SLisandro Dalcin dlflags1 = RTLD_NOW; 106ebd79076SLisandro Dalcin #endif 107*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 108*be1c6ad7SLisandro Dalcin dlflags2 = RTLD_LOCAL; 109*be1c6ad7SLisandro Dalcin #endif 110ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 1115673baf8SLisandro Dalcin if (flags & PETSC_DL_GLOBAL) 112*be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 113ebd79076SLisandro Dalcin #endif 114*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 115*be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 116*be1c6ad7SLisandro Dalcin #endif 117*be1c6ad7SLisandro Dalcin dlhandle = dlopen(name,dlflags1|dlflags2); 118ebd79076SLisandro Dalcin if (!dlhandle) { 119ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 120ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 121ebd79076SLisandro Dalcin #else 122ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 123ebd79076SLisandro Dalcin #endif 124*be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg) 125ebd79076SLisandro Dalcin } 1265673baf8SLisandro Dalcin 1275673baf8SLisandro Dalcin /* 1285673baf8SLisandro Dalcin --- unimplemented --- 1295673baf8SLisandro Dalcin */ 130ebd79076SLisandro Dalcin #else 131*be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 132ebd79076SLisandro Dalcin #endif 133ebd79076SLisandro Dalcin 134ebd79076SLisandro Dalcin *handle = (PetscDLHandle) dlhandle; 135ebd79076SLisandro Dalcin 136ebd79076SLisandro Dalcin PetscFunctionReturn(0); 137ebd79076SLisandro Dalcin } 138ebd79076SLisandro Dalcin 139ebd79076SLisandro Dalcin 140ebd79076SLisandro Dalcin #undef __FUNCT__ 141ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose" 142ebd79076SLisandro Dalcin /*@C 143ebd79076SLisandro Dalcin PetscDLClose - 144ebd79076SLisandro Dalcin @*/ 145ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 146ebd79076SLisandro Dalcin { 147ebd79076SLisandro Dalcin dlhandle_t dlhandle; 148ebd79076SLisandro Dalcin 149ebd79076SLisandro Dalcin PetscFunctionBegin; 150ebd79076SLisandro Dalcin PetscValidPointer(handle,1); 151ebd79076SLisandro Dalcin 152ebd79076SLisandro Dalcin dlhandle = (dlhandle_t) *handle; 153ebd79076SLisandro Dalcin 1545673baf8SLisandro Dalcin /* 1555673baf8SLisandro Dalcin --- FreeLibrary --- 1565673baf8SLisandro Dalcin */ 157ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 158*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1595673baf8SLisandro Dalcin if (FreeLibrary(dlhandle) == 0) { 1605673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 1615673baf8SLisandro Dalcin DWORD erc; 1625673baf8SLisandro Dalcin char *buff; 1635673baf8SLisandro Dalcin erc = GetLastError(); 1645673baf8SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 1655673baf8SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 1665673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 1675673baf8SLisandro Dalcin LocalFree(buff); 1685673baf8SLisandro Dalcin #else 1695673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 1705673baf8SLisandro Dalcin #endif 1715673baf8SLisandro Dalcin } 172*be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 173ebd79076SLisandro Dalcin 1745673baf8SLisandro Dalcin /* 1755673baf8SLisandro Dalcin --- dclose --- 1765673baf8SLisandro Dalcin */ 177ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 178*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 179*be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 180*be1c6ad7SLisandro Dalcin #endif 181ebd79076SLisandro Dalcin if (dlclose(dlhandle) < 0) { 182ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 183ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 184ebd79076SLisandro Dalcin #else 185ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 186ebd79076SLisandro Dalcin #endif 1875673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 188ebd79076SLisandro Dalcin } 1895673baf8SLisandro Dalcin 1905673baf8SLisandro Dalcin /* 1915673baf8SLisandro Dalcin --- unimplemented --- 1925673baf8SLisandro Dalcin */ 193ebd79076SLisandro Dalcin #else 194*be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 195ebd79076SLisandro Dalcin #endif 196ebd79076SLisandro Dalcin 197ebd79076SLisandro Dalcin *handle = PETSC_NULL; 198ebd79076SLisandro Dalcin 199ebd79076SLisandro Dalcin PetscFunctionReturn(0); 200ebd79076SLisandro Dalcin } 201ebd79076SLisandro Dalcin 202ebd79076SLisandro Dalcin 203ebd79076SLisandro Dalcin #undef __FUNCT__ 204ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym" 205ebd79076SLisandro Dalcin /*@C 206ebd79076SLisandro Dalcin PetscDLSym - 207ebd79076SLisandro Dalcin @*/ 2085673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 209ebd79076SLisandro Dalcin { 210ebd79076SLisandro Dalcin dlhandle_t dlhandle; 211ebd79076SLisandro Dalcin void *dlvalue; 212ebd79076SLisandro Dalcin 213ebd79076SLisandro Dalcin PetscFunctionBegin; 214ebd79076SLisandro Dalcin PetscValidCharPointer(symbol,2); 215ebd79076SLisandro Dalcin PetscValidPointer(value,3); 216ebd79076SLisandro Dalcin 217*be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 218*be1c6ad7SLisandro Dalcin *value = 0; 219ebd79076SLisandro Dalcin 2205673baf8SLisandro Dalcin /* 2215673baf8SLisandro Dalcin --- GetProcAddress --- 2225673baf8SLisandro Dalcin */ 223ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS) 224*be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 225*be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 226*be1c6ad7SLisandro Dalcin else 227*be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) GetCurrentProcess(); 228ebd79076SLisandro Dalcin dlvalue = GetProcAddress(dlhandle,symbol); 2295673baf8SLisandro Dalcin 2305673baf8SLisandro Dalcin /* 2315673baf8SLisandro Dalcin --- dlsym --- 2325673baf8SLisandro Dalcin */ 233ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 234*be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 235*be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 236*be1c6ad7SLisandro Dalcin else 237*be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 238*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 239*be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 240*be1c6ad7SLisandro Dalcin #endif 241ebd79076SLisandro Dalcin dlvalue = dlsym(dlhandle,symbol); 242*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 243*be1c6ad7SLisandro Dalcin if (!dlvalue) { /* dvalue could be actually NULL */ 244*be1c6ad7SLisandro Dalcin const char *errmsg = dlerror(); 245*be1c6ad7SLisandro Dalcin if (errmsg) { /* XXX Should we fail/inform about this? */ 246*be1c6ad7SLisandro Dalcin #if 0 247*be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_UNEXPECTED,"Unable to load symbol %s\n Error message from dlsym() %s\n",symbol,errmsg); 248*be1c6ad7SLisandro Dalcin #else 249*be1c6ad7SLisandro Dalcin errmsg = 0; 250*be1c6ad7SLisandro Dalcin #endif 251*be1c6ad7SLisandro Dalcin } 252*be1c6ad7SLisandro Dalcin } 253*be1c6ad7SLisandro Dalcin #endif 2545673baf8SLisandro Dalcin 2555673baf8SLisandro Dalcin /* 2565673baf8SLisandro Dalcin --- unimplemented --- 2575673baf8SLisandro Dalcin */ 258ebd79076SLisandro Dalcin #else 259*be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 260ebd79076SLisandro Dalcin #endif 261ebd79076SLisandro Dalcin 262ebd79076SLisandro Dalcin *value = dlvalue; 263ebd79076SLisandro Dalcin 264ebd79076SLisandro Dalcin PetscFunctionReturn(0); 265ebd79076SLisandro Dalcin } 266