1ebd79076SLisandro Dalcin #define PETSC_DLL 2ebd79076SLisandro Dalcin /* 3ebd79076SLisandro Dalcin Low-level routines for managing dynamic link libraries (DLLs). 4ebd79076SLisandro Dalcin */ 5ebd79076SLisandro Dalcin 6*7c4f633dSBarry Smith #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 20ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 21ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t; 22ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 23ebd79076SLisandro Dalcin typedef void* dlhandle_t; 24ebd79076SLisandro Dalcin #else 25ebd79076SLisandro Dalcin typedef void* dlhandle_t; 26ebd79076SLisandro Dalcin #endif 27ebd79076SLisandro Dalcin 28ebd79076SLisandro Dalcin #undef __FUNCT__ 29ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen" 30ebd79076SLisandro Dalcin /*@C 31ebd79076SLisandro Dalcin PetscDLOpen - 32ebd79076SLisandro Dalcin @*/ 335673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 34ebd79076SLisandro Dalcin { 35be1c6ad7SLisandro Dalcin int dlflags1,dlflags2; 36ebd79076SLisandro Dalcin dlhandle_t dlhandle; 37ebd79076SLisandro Dalcin 38ebd79076SLisandro Dalcin PetscFunctionBegin; 39ebd79076SLisandro Dalcin PetscValidCharPointer(name,1); 40ebd79076SLisandro Dalcin PetscValidPointer(handle,3); 41ebd79076SLisandro Dalcin 42be1c6ad7SLisandro Dalcin dlflags1 = 0; 43be1c6ad7SLisandro Dalcin dlflags2 = 0; 445673baf8SLisandro Dalcin dlhandle = (dlhandle_t) 0; 45be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle) 0; 46ebd79076SLisandro Dalcin 475673baf8SLisandro Dalcin /* 485673baf8SLisandro Dalcin --- LoadLibrary --- 495673baf8SLisandro Dalcin */ 50be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 51be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 52ebd79076SLisandro Dalcin if (!dlhandle) { 53ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 54ebd79076SLisandro Dalcin PetscErrorCode ierr; 55ebd79076SLisandro Dalcin DWORD erc; 56b3bb0f5eSLisandro Dalcin char *buff = NULL; 57ebd79076SLisandro Dalcin erc = GetLastError(); 58ebd79076SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 59ebd79076SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 60ebd79076SLisandro Dalcin ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 61be1c6ad7SLisandro Dalcin "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 62ebd79076SLisandro Dalcin LocalFree(buff); 63ebd79076SLisandro Dalcin PetscFunctionReturn(ierr); 64ebd79076SLisandro Dalcin #else 65be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 66ebd79076SLisandro Dalcin #endif 67ebd79076SLisandro Dalcin } 685673baf8SLisandro Dalcin 695673baf8SLisandro Dalcin /* 705673baf8SLisandro Dalcin --- dlopen --- 715673baf8SLisandro Dalcin */ 72a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 73ebd79076SLisandro Dalcin /* 74ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 75ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 76ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 77ebd79076SLisandro Dalcin with dlopen() 78ebd79076SLisandro Dalcin */ 79be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 80be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 81be1c6ad7SLisandro Dalcin #endif 82ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 835673baf8SLisandro Dalcin if (flags & PETSC_DL_NOW) 84be1c6ad7SLisandro Dalcin dlflags1 = RTLD_NOW; 85ebd79076SLisandro Dalcin #endif 86ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 87be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 88ebd79076SLisandro Dalcin #endif 89b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 90b3bb0f5eSLisandro Dalcin if (flags & PETSC_DL_LOCAL) 91b3bb0f5eSLisandro Dalcin dlflags2 = RTLD_LOCAL; 92b3bb0f5eSLisandro Dalcin #endif 93be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 94be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 95be1c6ad7SLisandro Dalcin #endif 96be1c6ad7SLisandro Dalcin dlhandle = dlopen(name,dlflags1|dlflags2); 97ebd79076SLisandro Dalcin if (!dlhandle) { 98ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 99ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 100ebd79076SLisandro Dalcin #else 101ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 102ebd79076SLisandro Dalcin #endif 103be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg) 104ebd79076SLisandro Dalcin } 1055673baf8SLisandro Dalcin 1065673baf8SLisandro Dalcin /* 1075673baf8SLisandro Dalcin --- unimplemented --- 1085673baf8SLisandro Dalcin */ 109ebd79076SLisandro Dalcin #else 110be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 111ebd79076SLisandro Dalcin #endif 112ebd79076SLisandro Dalcin 113ebd79076SLisandro Dalcin *handle = (PetscDLHandle) dlhandle; 114ebd79076SLisandro Dalcin 115ebd79076SLisandro Dalcin PetscFunctionReturn(0); 116ebd79076SLisandro Dalcin } 117ebd79076SLisandro Dalcin 118ebd79076SLisandro Dalcin 119ebd79076SLisandro Dalcin #undef __FUNCT__ 120ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose" 121ebd79076SLisandro Dalcin /*@C 122ebd79076SLisandro Dalcin PetscDLClose - 123ebd79076SLisandro Dalcin @*/ 124ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 125ebd79076SLisandro Dalcin { 126ebd79076SLisandro Dalcin dlhandle_t dlhandle; 127ebd79076SLisandro Dalcin 128ebd79076SLisandro Dalcin PetscFunctionBegin; 129ebd79076SLisandro Dalcin PetscValidPointer(handle,1); 130ebd79076SLisandro Dalcin 131ebd79076SLisandro Dalcin dlhandle = (dlhandle_t) *handle; 132ebd79076SLisandro Dalcin 1335673baf8SLisandro Dalcin /* 1345673baf8SLisandro Dalcin --- FreeLibrary --- 1355673baf8SLisandro Dalcin */ 136ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 137be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1385673baf8SLisandro Dalcin if (FreeLibrary(dlhandle) == 0) { 1395673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 140b3bb0f5eSLisandro Dalcin char *buff = NULL; 141a21658a3SLisandro Dalcin DWORD erc = GetLastError(); 1425673baf8SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 1435673baf8SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 1445673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 1455673baf8SLisandro Dalcin LocalFree(buff); 1465673baf8SLisandro Dalcin #else 1475673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 1485673baf8SLisandro Dalcin #endif 1495673baf8SLisandro Dalcin } 150be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 151ebd79076SLisandro Dalcin 1525673baf8SLisandro Dalcin /* 1535673baf8SLisandro Dalcin --- dclose --- 1545673baf8SLisandro Dalcin */ 155ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 156a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE) 157be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 158be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 159be1c6ad7SLisandro Dalcin #endif 160ebd79076SLisandro Dalcin if (dlclose(dlhandle) < 0) { 161ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 162ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 163ebd79076SLisandro Dalcin #else 164ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 165ebd79076SLisandro Dalcin #endif 1665673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 167ebd79076SLisandro Dalcin } 168a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */ 1695673baf8SLisandro Dalcin 1705673baf8SLisandro Dalcin /* 1715673baf8SLisandro Dalcin --- unimplemented --- 1725673baf8SLisandro Dalcin */ 173ebd79076SLisandro Dalcin #else 174be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 175ebd79076SLisandro Dalcin #endif 176ebd79076SLisandro Dalcin 177ebd79076SLisandro Dalcin *handle = PETSC_NULL; 178ebd79076SLisandro Dalcin 179ebd79076SLisandro Dalcin PetscFunctionReturn(0); 180ebd79076SLisandro Dalcin } 181ebd79076SLisandro Dalcin 182ebd79076SLisandro Dalcin 183ebd79076SLisandro Dalcin #undef __FUNCT__ 184ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym" 185ebd79076SLisandro Dalcin /*@C 186ebd79076SLisandro Dalcin PetscDLSym - 187ebd79076SLisandro Dalcin @*/ 1885673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 189ebd79076SLisandro Dalcin { 190ebd79076SLisandro Dalcin dlhandle_t dlhandle; 191ebd79076SLisandro Dalcin void *dlvalue; 192ebd79076SLisandro Dalcin 193ebd79076SLisandro Dalcin PetscFunctionBegin; 194ebd79076SLisandro Dalcin PetscValidCharPointer(symbol,2); 195ebd79076SLisandro Dalcin PetscValidPointer(value,3); 196ebd79076SLisandro Dalcin 197be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 198a21658a3SLisandro Dalcin dlvalue = (void *) 0; 199a21658a3SLisandro Dalcin *value = (void *) 0; 200ebd79076SLisandro Dalcin 2015673baf8SLisandro Dalcin /* 2025673baf8SLisandro Dalcin --- GetProcAddress --- 2035673baf8SLisandro Dalcin */ 204a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 205a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 206be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 207be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 208be1c6ad7SLisandro Dalcin else 209be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) GetCurrentProcess(); 210ebd79076SLisandro Dalcin dlvalue = GetProcAddress(dlhandle,symbol); 211a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 212a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 213a21658a3SLisandro Dalcin #endif 214a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2155673baf8SLisandro Dalcin 2165673baf8SLisandro Dalcin /* 2175673baf8SLisandro Dalcin --- dlsym --- 2185673baf8SLisandro Dalcin */ 219ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 220a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 221be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 222be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 223be1c6ad7SLisandro Dalcin else 224be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 225be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 226be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 227be1c6ad7SLisandro Dalcin #endif 228ebd79076SLisandro Dalcin dlvalue = dlsym(dlhandle,symbol); 229be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 230b3bb0f5eSLisandro Dalcin dlerror(); /* clear any previous error */ 231be1c6ad7SLisandro Dalcin #endif 232a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLSYM */ 2335673baf8SLisandro Dalcin 2345673baf8SLisandro Dalcin /* 2355673baf8SLisandro Dalcin --- unimplemented --- 2365673baf8SLisandro Dalcin */ 237ebd79076SLisandro Dalcin #else 238be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 239ebd79076SLisandro Dalcin #endif 240ebd79076SLisandro Dalcin 241ebd79076SLisandro Dalcin *value = dlvalue; 242ebd79076SLisandro Dalcin 243ebd79076SLisandro Dalcin PetscFunctionReturn(0); 244ebd79076SLisandro Dalcin } 245