1ebd79076SLisandro Dalcin #define PETSC_DLL 2ebd79076SLisandro Dalcin /* 3ebd79076SLisandro Dalcin Low-level routines for managing dynamic link libraries (DLLs). 4ebd79076SLisandro Dalcin */ 5ebd79076SLisandro Dalcin 6*b3bb0f5eSLisandro Dalcin #include "src/sys/dll/dlimpl.h" 7ebd79076SLisandro Dalcin 8ebd79076SLisandro Dalcin /* XXX Should be done better !!!*/ 9be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 10ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H 11ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 12ebd79076SLisandro Dalcin #endif 13ebd79076SLisandro Dalcin 14ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 15ebd79076SLisandro Dalcin #include <windows.h> 16be1c6ad7SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 17ebd79076SLisandro Dalcin #include <dlfcn.h> 18ebd79076SLisandro Dalcin #endif 19ebd79076SLisandro Dalcin 20be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */ 21be1c6ad7SLisandro Dalcin /* Just for testing, REMOVE THIS when done */ 22ebd79076SLisandro Dalcin #if 0 23ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H 24ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 25ebd79076SLisandro Dalcin #elif 0 26ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H 27ebd79076SLisandro Dalcin #define PETSC_HAVE_WINDOWS_H 28be1c6ad7SLisandro Dalcin #define PETSC_HAVE_LOADLIBRARY 29ebd79076SLisandro Dalcin #define PETSC_HAVE_GETPROCADDRESS 30be1c6ad7SLisandro Dalcin #define PETSC_HAVE_FREELIBRARY 31ebd79076SLisandro Dalcin #define HMODULE int 32ebd79076SLisandro Dalcin extern HMODULE LoadLibrary(const char*); 335673baf8SLisandro Dalcin extern int FreeLibrary(HMODULE); 34ebd79076SLisandro Dalcin extern HMODULE GetCurrentProcess(void); 35ebd79076SLisandro Dalcin extern void* GetProcAddress(HMODULE,const char*); 36ebd79076SLisandro Dalcin #endif 37be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */ 38be1c6ad7SLisandro Dalcin 39ebd79076SLisandro Dalcin 40ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 41ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t; 42ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 43ebd79076SLisandro Dalcin typedef void* dlhandle_t; 44ebd79076SLisandro Dalcin #else 45ebd79076SLisandro Dalcin typedef void* dlhandle_t; 46ebd79076SLisandro Dalcin #endif 47ebd79076SLisandro Dalcin 48ebd79076SLisandro Dalcin #undef __FUNCT__ 49ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen" 50ebd79076SLisandro Dalcin /*@C 51ebd79076SLisandro Dalcin PetscDLOpen - 52ebd79076SLisandro Dalcin @*/ 535673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 54ebd79076SLisandro Dalcin { 55be1c6ad7SLisandro Dalcin int dlflags1,dlflags2; 56ebd79076SLisandro Dalcin dlhandle_t dlhandle; 57ebd79076SLisandro Dalcin 58ebd79076SLisandro Dalcin PetscFunctionBegin; 59ebd79076SLisandro Dalcin PetscValidCharPointer(name, 1); 60ebd79076SLisandro Dalcin PetscValidPointer(handle, 3); 61ebd79076SLisandro Dalcin 62be1c6ad7SLisandro Dalcin dlflags1 = 0; 63be1c6ad7SLisandro Dalcin dlflags2 = 0; 645673baf8SLisandro Dalcin dlhandle = (dlhandle_t) 0; 65be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle) 0; 66ebd79076SLisandro Dalcin 675673baf8SLisandro Dalcin /* 685673baf8SLisandro Dalcin --- LoadLibrary --- 695673baf8SLisandro Dalcin */ 70be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 71be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 72ebd79076SLisandro Dalcin if (!dlhandle) { 73ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 74ebd79076SLisandro Dalcin PetscErrorCode ierr; 75ebd79076SLisandro Dalcin DWORD erc; 76*b3bb0f5eSLisandro Dalcin char *buff = NULL; 77ebd79076SLisandro Dalcin erc = GetLastError(); 78ebd79076SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 79ebd79076SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 80ebd79076SLisandro Dalcin ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 81be1c6ad7SLisandro Dalcin "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 82ebd79076SLisandro Dalcin LocalFree(buff); 83ebd79076SLisandro Dalcin PetscFunctionReturn(ierr); 84ebd79076SLisandro Dalcin #else 85be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 86ebd79076SLisandro Dalcin #endif 87ebd79076SLisandro Dalcin } 885673baf8SLisandro Dalcin 895673baf8SLisandro Dalcin /* 905673baf8SLisandro Dalcin --- dlopen --- 915673baf8SLisandro Dalcin */ 92ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 93ebd79076SLisandro Dalcin /* 94ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 95ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 96ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 97ebd79076SLisandro Dalcin with dlopen() 98ebd79076SLisandro Dalcin */ 99be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 100be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 101be1c6ad7SLisandro Dalcin #endif 102ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 1035673baf8SLisandro Dalcin if (flags & PETSC_DL_NOW) 104be1c6ad7SLisandro Dalcin dlflags1 = RTLD_NOW; 105ebd79076SLisandro Dalcin #endif 106ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 107be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 108ebd79076SLisandro Dalcin #endif 109*b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 110*b3bb0f5eSLisandro Dalcin if (flags & PETSC_DL_LOCAL) 111*b3bb0f5eSLisandro Dalcin dlflags2 = RTLD_LOCAL; 112*b3bb0f5eSLisandro Dalcin #endif 113be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 114be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 115be1c6ad7SLisandro Dalcin #endif 116be1c6ad7SLisandro Dalcin dlhandle = dlopen(name,dlflags1|dlflags2); 117ebd79076SLisandro Dalcin if (!dlhandle) { 118ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 119ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 120ebd79076SLisandro Dalcin #else 121ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 122ebd79076SLisandro Dalcin #endif 123be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg) 124ebd79076SLisandro Dalcin } 1255673baf8SLisandro Dalcin 1265673baf8SLisandro Dalcin /* 1275673baf8SLisandro Dalcin --- unimplemented --- 1285673baf8SLisandro Dalcin */ 129ebd79076SLisandro Dalcin #else 130be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 131ebd79076SLisandro Dalcin #endif 132ebd79076SLisandro Dalcin 133ebd79076SLisandro Dalcin *handle = (PetscDLHandle) dlhandle; 134ebd79076SLisandro Dalcin 135ebd79076SLisandro Dalcin PetscFunctionReturn(0); 136ebd79076SLisandro Dalcin } 137ebd79076SLisandro Dalcin 138ebd79076SLisandro Dalcin 139ebd79076SLisandro Dalcin #undef __FUNCT__ 140ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose" 141ebd79076SLisandro Dalcin /*@C 142ebd79076SLisandro Dalcin PetscDLClose - 143ebd79076SLisandro Dalcin @*/ 144ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 145ebd79076SLisandro Dalcin { 146ebd79076SLisandro Dalcin dlhandle_t dlhandle; 147ebd79076SLisandro Dalcin 148ebd79076SLisandro Dalcin PetscFunctionBegin; 149ebd79076SLisandro Dalcin PetscValidPointer(handle,1); 150ebd79076SLisandro Dalcin 151ebd79076SLisandro Dalcin dlhandle = (dlhandle_t) *handle; 152ebd79076SLisandro Dalcin 1535673baf8SLisandro Dalcin /* 1545673baf8SLisandro Dalcin --- FreeLibrary --- 1555673baf8SLisandro Dalcin */ 156ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 157be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1585673baf8SLisandro Dalcin if (FreeLibrary(dlhandle) == 0) { 1595673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 1605673baf8SLisandro Dalcin DWORD erc; 161*b3bb0f5eSLisandro Dalcin char *buff = NULL; 1625673baf8SLisandro Dalcin erc = GetLastError(); 1635673baf8SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 1645673baf8SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 1655673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 1665673baf8SLisandro Dalcin LocalFree(buff); 1675673baf8SLisandro Dalcin #else 1685673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 1695673baf8SLisandro Dalcin #endif 1705673baf8SLisandro Dalcin } 171be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 172ebd79076SLisandro Dalcin 1735673baf8SLisandro Dalcin /* 1745673baf8SLisandro Dalcin --- dclose --- 1755673baf8SLisandro Dalcin */ 176ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 177be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 178be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 179be1c6ad7SLisandro Dalcin #endif 180ebd79076SLisandro Dalcin if (dlclose(dlhandle) < 0) { 181ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 182ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 183ebd79076SLisandro Dalcin #else 184ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 185ebd79076SLisandro Dalcin #endif 1865673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 187ebd79076SLisandro Dalcin } 1885673baf8SLisandro Dalcin 1895673baf8SLisandro Dalcin /* 1905673baf8SLisandro Dalcin --- unimplemented --- 1915673baf8SLisandro Dalcin */ 192ebd79076SLisandro Dalcin #else 193be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 194ebd79076SLisandro Dalcin #endif 195ebd79076SLisandro Dalcin 196ebd79076SLisandro Dalcin *handle = PETSC_NULL; 197ebd79076SLisandro Dalcin 198ebd79076SLisandro Dalcin PetscFunctionReturn(0); 199ebd79076SLisandro Dalcin } 200ebd79076SLisandro Dalcin 201ebd79076SLisandro Dalcin 202ebd79076SLisandro Dalcin #undef __FUNCT__ 203ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym" 204ebd79076SLisandro Dalcin /*@C 205ebd79076SLisandro Dalcin PetscDLSym - 206ebd79076SLisandro Dalcin @*/ 2075673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 208ebd79076SLisandro Dalcin { 209ebd79076SLisandro Dalcin dlhandle_t dlhandle; 210ebd79076SLisandro Dalcin void *dlvalue; 211ebd79076SLisandro Dalcin 212ebd79076SLisandro Dalcin PetscFunctionBegin; 213ebd79076SLisandro Dalcin PetscValidCharPointer(symbol,2); 214ebd79076SLisandro Dalcin PetscValidPointer(value,3); 215ebd79076SLisandro Dalcin 216be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 217be1c6ad7SLisandro Dalcin *value = 0; 218ebd79076SLisandro Dalcin 2195673baf8SLisandro Dalcin /* 2205673baf8SLisandro Dalcin --- GetProcAddress --- 2215673baf8SLisandro Dalcin */ 222ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS) 223be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 224be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 225be1c6ad7SLisandro Dalcin else 226be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) GetCurrentProcess(); 227ebd79076SLisandro Dalcin dlvalue = GetProcAddress(dlhandle,symbol); 2285673baf8SLisandro Dalcin 2295673baf8SLisandro Dalcin /* 2305673baf8SLisandro Dalcin --- dlsym --- 2315673baf8SLisandro Dalcin */ 232ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 233be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 234be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 235be1c6ad7SLisandro Dalcin else 236be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 237be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 238be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 239be1c6ad7SLisandro Dalcin #endif 240ebd79076SLisandro Dalcin dlvalue = dlsym(dlhandle,symbol); 241be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 242*b3bb0f5eSLisandro Dalcin dlerror(); /* clear any previous error */ 243be1c6ad7SLisandro Dalcin #endif 2445673baf8SLisandro Dalcin 2455673baf8SLisandro Dalcin /* 2465673baf8SLisandro Dalcin --- unimplemented --- 2475673baf8SLisandro Dalcin */ 248ebd79076SLisandro Dalcin #else 249be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 250ebd79076SLisandro Dalcin #endif 251ebd79076SLisandro Dalcin 252ebd79076SLisandro Dalcin *value = dlvalue; 253ebd79076SLisandro Dalcin 254ebd79076SLisandro Dalcin PetscFunctionReturn(0); 255ebd79076SLisandro Dalcin } 256