1ebd79076SLisandro Dalcin #define PETSC_DLL 2ebd79076SLisandro Dalcin /* 3ebd79076SLisandro Dalcin Low-level routines for managing dynamic link libraries (DLLs). 4ebd79076SLisandro Dalcin */ 5ebd79076SLisandro Dalcin 67c4f633dSBarry 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; 22*6ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t; 23ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 24ebd79076SLisandro Dalcin typedef void* dlhandle_t; 25*6ea75d68SLisandro Dalcin typedef void* dlsymbol_t; 26ebd79076SLisandro Dalcin #else 27ebd79076SLisandro Dalcin typedef void* dlhandle_t; 28*6ea75d68SLisandro Dalcin typedef void* dlsymbol_t; 29ebd79076SLisandro Dalcin #endif 30ebd79076SLisandro Dalcin 31ebd79076SLisandro Dalcin #undef __FUNCT__ 32ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen" 33ebd79076SLisandro Dalcin /*@C 34ebd79076SLisandro Dalcin PetscDLOpen - 35ebd79076SLisandro Dalcin @*/ 365673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 37ebd79076SLisandro Dalcin { 38be1c6ad7SLisandro Dalcin int dlflags1,dlflags2; 39ebd79076SLisandro Dalcin dlhandle_t dlhandle; 40ebd79076SLisandro Dalcin 41ebd79076SLisandro Dalcin PetscFunctionBegin; 42ebd79076SLisandro Dalcin PetscValidCharPointer(name,1); 43ebd79076SLisandro Dalcin PetscValidPointer(handle,3); 44ebd79076SLisandro Dalcin 45be1c6ad7SLisandro Dalcin dlflags1 = 0; 46be1c6ad7SLisandro Dalcin dlflags2 = 0; 475673baf8SLisandro Dalcin dlhandle = (dlhandle_t) 0; 48be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle) 0; 49ebd79076SLisandro Dalcin 505673baf8SLisandro Dalcin /* 515673baf8SLisandro Dalcin --- LoadLibrary --- 525673baf8SLisandro Dalcin */ 53be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 54be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 55ebd79076SLisandro Dalcin if (!dlhandle) { 56ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 57ebd79076SLisandro Dalcin PetscErrorCode ierr; 58ebd79076SLisandro Dalcin DWORD erc; 59b3bb0f5eSLisandro Dalcin char *buff = NULL; 60ebd79076SLisandro Dalcin erc = GetLastError(); 61ebd79076SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 62ebd79076SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 63ebd79076SLisandro Dalcin ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1, 64be1c6ad7SLisandro Dalcin "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 65ebd79076SLisandro Dalcin LocalFree(buff); 66ebd79076SLisandro Dalcin PetscFunctionReturn(ierr); 67ebd79076SLisandro Dalcin #else 68be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 69ebd79076SLisandro Dalcin #endif 70ebd79076SLisandro Dalcin } 715673baf8SLisandro Dalcin 725673baf8SLisandro Dalcin /* 735673baf8SLisandro Dalcin --- dlopen --- 745673baf8SLisandro Dalcin */ 75a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 76ebd79076SLisandro Dalcin /* 77ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 78ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 79ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 80ebd79076SLisandro Dalcin with dlopen() 81ebd79076SLisandro Dalcin */ 82be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 83be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 84be1c6ad7SLisandro Dalcin #endif 85ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 865673baf8SLisandro Dalcin if (flags & PETSC_DL_NOW) 87be1c6ad7SLisandro Dalcin dlflags1 = RTLD_NOW; 88ebd79076SLisandro Dalcin #endif 89ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 90be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 91ebd79076SLisandro Dalcin #endif 92b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 93b3bb0f5eSLisandro Dalcin if (flags & PETSC_DL_LOCAL) 94b3bb0f5eSLisandro Dalcin dlflags2 = RTLD_LOCAL; 95b3bb0f5eSLisandro Dalcin #endif 96be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 97be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 98be1c6ad7SLisandro Dalcin #endif 99be1c6ad7SLisandro Dalcin dlhandle = dlopen(name,dlflags1|dlflags2); 100ebd79076SLisandro Dalcin if (!dlhandle) { 101ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 102ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 103ebd79076SLisandro Dalcin #else 104ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 105ebd79076SLisandro Dalcin #endif 106be1c6ad7SLisandro Dalcin SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg) 107ebd79076SLisandro Dalcin } 1085673baf8SLisandro Dalcin 1095673baf8SLisandro Dalcin /* 1105673baf8SLisandro Dalcin --- unimplemented --- 1115673baf8SLisandro Dalcin */ 112ebd79076SLisandro Dalcin #else 113be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 114ebd79076SLisandro Dalcin #endif 115ebd79076SLisandro Dalcin 116ebd79076SLisandro Dalcin *handle = (PetscDLHandle) dlhandle; 117ebd79076SLisandro Dalcin 118ebd79076SLisandro Dalcin PetscFunctionReturn(0); 119ebd79076SLisandro Dalcin } 120ebd79076SLisandro Dalcin 121ebd79076SLisandro Dalcin 122ebd79076SLisandro Dalcin #undef __FUNCT__ 123ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose" 124ebd79076SLisandro Dalcin /*@C 125ebd79076SLisandro Dalcin PetscDLClose - 126ebd79076SLisandro Dalcin @*/ 127ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 128ebd79076SLisandro Dalcin { 129ebd79076SLisandro Dalcin dlhandle_t dlhandle; 130ebd79076SLisandro Dalcin 131ebd79076SLisandro Dalcin PetscFunctionBegin; 132ebd79076SLisandro Dalcin PetscValidPointer(handle,1); 133ebd79076SLisandro Dalcin 134ebd79076SLisandro Dalcin dlhandle = (dlhandle_t) *handle; 135ebd79076SLisandro Dalcin 1365673baf8SLisandro Dalcin /* 1375673baf8SLisandro Dalcin --- FreeLibrary --- 1385673baf8SLisandro Dalcin */ 139ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 140be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1415673baf8SLisandro Dalcin if (FreeLibrary(dlhandle) == 0) { 1425673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 143b3bb0f5eSLisandro Dalcin char *buff = NULL; 144a21658a3SLisandro Dalcin DWORD erc = GetLastError(); 1455673baf8SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 1465673baf8SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 1475673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 1485673baf8SLisandro Dalcin LocalFree(buff); 1495673baf8SLisandro Dalcin #else 1505673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 1515673baf8SLisandro Dalcin #endif 1525673baf8SLisandro Dalcin } 153be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 154ebd79076SLisandro Dalcin 1555673baf8SLisandro Dalcin /* 1565673baf8SLisandro Dalcin --- dclose --- 1575673baf8SLisandro Dalcin */ 158ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 159a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE) 160be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 161be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 162be1c6ad7SLisandro Dalcin #endif 163ebd79076SLisandro Dalcin if (dlclose(dlhandle) < 0) { 164ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 165ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 166ebd79076SLisandro Dalcin #else 167ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 168ebd79076SLisandro Dalcin #endif 1695673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 170ebd79076SLisandro Dalcin } 171a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */ 1725673baf8SLisandro Dalcin 1735673baf8SLisandro Dalcin /* 1745673baf8SLisandro Dalcin --- unimplemented --- 1755673baf8SLisandro Dalcin */ 176ebd79076SLisandro Dalcin #else 177be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 178ebd79076SLisandro Dalcin #endif 179ebd79076SLisandro Dalcin 180ebd79076SLisandro Dalcin *handle = PETSC_NULL; 181ebd79076SLisandro Dalcin 182ebd79076SLisandro Dalcin PetscFunctionReturn(0); 183ebd79076SLisandro Dalcin } 184ebd79076SLisandro Dalcin 185ebd79076SLisandro Dalcin 186ebd79076SLisandro Dalcin #undef __FUNCT__ 187ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym" 188ebd79076SLisandro Dalcin /*@C 189ebd79076SLisandro Dalcin PetscDLSym - 190ebd79076SLisandro Dalcin @*/ 1915673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 192ebd79076SLisandro Dalcin { 193ebd79076SLisandro Dalcin dlhandle_t dlhandle; 194*6ea75d68SLisandro Dalcin dlsymbol_t dlsymbol; 195ebd79076SLisandro Dalcin 196ebd79076SLisandro Dalcin PetscFunctionBegin; 197ebd79076SLisandro Dalcin PetscValidCharPointer(symbol,2); 198ebd79076SLisandro Dalcin PetscValidPointer(value,3); 199ebd79076SLisandro Dalcin 200be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 201*6ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) 0; 202*6ea75d68SLisandro Dalcin 203a21658a3SLisandro Dalcin *value = (void *) 0; 204ebd79076SLisandro Dalcin 2055673baf8SLisandro Dalcin /* 2065673baf8SLisandro Dalcin --- GetProcAddress --- 2075673baf8SLisandro Dalcin */ 208a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 209a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 210be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 211be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 212be1c6ad7SLisandro Dalcin else 213be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) GetCurrentProcess(); 214*6ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol); 215a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 216a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 217a21658a3SLisandro Dalcin #endif 218a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2195673baf8SLisandro Dalcin 2205673baf8SLisandro Dalcin /* 2215673baf8SLisandro Dalcin --- dlsym --- 2225673baf8SLisandro Dalcin */ 223ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 224a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 225be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 226be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 227be1c6ad7SLisandro Dalcin else 228be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 229be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 230be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 231be1c6ad7SLisandro Dalcin #endif 232*6ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol); 233be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 234b3bb0f5eSLisandro Dalcin dlerror(); /* clear any previous error */ 235be1c6ad7SLisandro Dalcin #endif 236a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLSYM */ 2375673baf8SLisandro Dalcin 2385673baf8SLisandro Dalcin /* 2395673baf8SLisandro Dalcin --- unimplemented --- 2405673baf8SLisandro Dalcin */ 241ebd79076SLisandro Dalcin #else 242be1c6ad7SLisandro Dalcin SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 243ebd79076SLisandro Dalcin #endif 244ebd79076SLisandro Dalcin 245*6ea75d68SLisandro Dalcin *value = *((void**)&dlsymbol); 246ebd79076SLisandro Dalcin 247ebd79076SLisandro Dalcin PetscFunctionReturn(0); 248ebd79076SLisandro Dalcin } 249