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