Actual source code: dlimpl.c

  1: #define PETSC_DLL
  2: /*
  3:    Low-level routines for managing dynamic link libraries (DLLs).
  4: */

 6:  #include ../src/sys/dll/dlimpl.h

  8: /* XXX Should be done better !!!*/
  9: #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
 10: #undef PETSC_HAVE_WINDOWS_H
 11: #undef PETSC_HAVE_DLFCN_H
 12: #endif

 14: #if defined(PETSC_HAVE_WINDOWS_H)
 15: #include <windows.h>
 16: #elif defined(PETSC_HAVE_DLFCN_H)
 17: #include <dlfcn.h>
 18: #endif

 20: #if defined(PETSC_HAVE_WINDOWS_H)
 21: typedef HMODULE dlhandle_t;
 22: typedef FARPROC dlsymbol_t;
 23: #elif defined(PETSC_HAVE_DLFCN_H)
 24: typedef void* dlhandle_t;
 25: typedef void* dlsymbol_t;
 26: #else
 27: typedef void* dlhandle_t;
 28: typedef void* dlsymbol_t;
 29: #endif

 33: /*@C
 34:    PetscDLOpen - opens dynamic library

 36:    Not Collective

 38:    Input Parameters:
 39: +    name - name of library
 40: -    flags - options on how to open library

 42:    Output Parameter:
 43: .    handle

 45:    Level: developer

 47: @*/
 48: PetscErrorCode  PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
 49: {
 50:   int        dlflags1,dlflags2;
 51:   dlhandle_t dlhandle;


 57:   dlflags1 = 0;
 58:   dlflags2 = 0;
 59:   dlhandle = (dlhandle_t) 0;
 60:   *handle  = (PetscDLHandle) 0;

 62:   /* 
 63:      --- LoadLibrary ---
 64:   */
 65: #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
 66:   dlhandle = LoadLibrary(name);
 67:   if (!dlhandle) {
 68: #if defined(PETSC_HAVE_GETLASTERROR)
 70:     DWORD erc;
 71:     char  *buff = NULL;
 72:     erc = GetLastError();
 73:     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
 74:                   NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
 75:     PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
 76:                       "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
 77:     LocalFree(buff);
 78:     PetscFunctionReturn(ierr);
 79: #else
 80:     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
 81: #endif
 82:   }

 84:   /* 
 85:      --- dlopen ---
 86:   */
 87: #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
 88:   /*
 89:       Mode indicates symbols required by symbol loaded with dlsym() 
 90:      are only loaded when required (not all together) also indicates
 91:      symbols required can be contained in other libraries also opened
 92:      with dlopen()
 93:   */
 94: #if defined(PETSC_HAVE_RTLD_LAZY)
 95:   dlflags1 = RTLD_LAZY;
 96: #endif
 97: #if defined(PETSC_HAVE_RTLD_NOW)
 98:   if (flags & PETSC_DL_NOW)
 99:     dlflags1 = RTLD_NOW;
100: #endif
101: #if defined(PETSC_HAVE_RTLD_GLOBAL)
102:   dlflags2 = RTLD_GLOBAL;
103: #endif
104: #if defined(PETSC_HAVE_RTLD_LOCAL)
105:   if (flags & PETSC_DL_LOCAL)
106:     dlflags2 = RTLD_LOCAL;
107: #endif
108: #if defined(PETSC_HAVE_DLERROR)
109:   dlerror(); /* clear any previous error */
110: #endif
111:   dlhandle = dlopen(name,dlflags1|dlflags2);
112:   if (!dlhandle) {
113: #if defined(PETSC_HAVE_DLERROR)
114:     const char *errmsg = dlerror();
115: #else
116:     const char *errmsg = "unavailable";
117: #endif
118:     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n",name,errmsg)
119:   }

121:   /* 
122:      --- unimplemented ---
123:   */
124: #else
125:   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
126: #endif

128:   *handle = (PetscDLHandle) dlhandle;

130:   return(0);
131: }


136: /*@C
137:    PetscDLClose -  closes a dynamic library

139:    Not Collective

141:   Input Parameter:
142: .   handle - the handle for the library obtained with PetscDLOpen()

144:   Level: developer
145: @*/
146: PetscErrorCode  PetscDLClose(PetscDLHandle *handle)
147: {
148:   dlhandle_t dlhandle;


153:   dlhandle = (dlhandle_t) *handle;

155:   /* 
156:      --- FreeLibrary ---
157:   */
158: #if defined(PETSC_HAVE_WINDOWS_H)
159: #if defined(PETSC_HAVE_FREELIBRARY)
160:   if (FreeLibrary(dlhandle) == 0) {
161: #if defined(PETSC_HAVE_GETLASTERROR)
162:     char  *buff = NULL;
163:     DWORD erc   = GetLastError();
164:     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
165:                   NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
166:     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
167:     LocalFree(buff);
168: #else
169:     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
170: #endif
171:   }
172: #endif /* !PETSC_HAVE_FREELIBRARY */

174:   /* 
175:      --- dclose --- 
176:   */
177: #elif defined(PETSC_HAVE_DLFCN_H)
178: #if defined(PETSC_HAVE_DLCLOSE)
179: #if defined(PETSC_HAVE_DLERROR)
180:   dlerror(); /* clear any previous error */
181: #endif
182:   if (dlclose(dlhandle) < 0) {
183: #if defined(PETSC_HAVE_DLERROR)
184:     const char *errmsg = dlerror();
185: #else
186:     const char *errmsg = "unavailable";
187: #endif
188:     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
189:   }
190: #endif /* !PETSC_HAVE_DLCLOSE */

192:   /* 
193:      --- unimplemented --- 
194:   */
195: #else
196:   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
197: #endif

199:   *handle = PETSC_NULL;

201:   return(0);
202: }


207: /*@C
208:    PetscDLSym - finds a symbol in a dynamic library

210:    Not Collective

212:    Input Parameters:
213: +   handle - obtained with PetscDLOpen()
214: -   symbol - name of symbol

216:    Output Parameter:
217: .   value - pointer to the function

219:    Level: developer

221: @*/
222: PetscErrorCode  PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
223: {
224:   dlhandle_t dlhandle;
225:   dlsymbol_t dlsymbol;


231:   dlhandle = (dlhandle_t) 0;
232:   dlsymbol = (dlsymbol_t) 0;

234:   *value   = (void *) 0;

236:   /* 
237:      --- GetProcAddress ---
238:   */
239: #if defined(PETSC_HAVE_WINDOWS_H) 
240: #if defined(PETSC_HAVE_GETPROCADDRESS)
241:   if (handle != PETSC_NULL)
242:     dlhandle = (dlhandle_t) handle;
243:   else
244:     dlhandle = (dlhandle_t) GetCurrentProcess();
245:   dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
246: #if defined(PETSC_HAVE_SETLASTERROR)
247:   SetLastError((DWORD)0); /* clear any previous error */
248: #endif
249: #endif /* !PETSC_HAVE_GETPROCADDRESS */

251:   /* 
252:      --- dlsym ---
253:   */
254: #elif defined(PETSC_HAVE_DLFCN_H)
255: #if defined(PETSC_HAVE_DLSYM)
256:   if (handle != PETSC_NULL)
257:     dlhandle = (dlhandle_t) handle;
258:   else
259:     dlhandle = (dlhandle_t) 0;
260: #if defined(PETSC_HAVE_DLERROR)
261:   dlerror(); /* clear any previous error */
262: #endif
263:   dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
264: #if defined(PETSC_HAVE_DLERROR)
265:   dlerror(); /* clear any previous error */
266: #endif
267: #endif /* !PETSC_HAVE_DLSYM */

269:   /* 
270:      --- unimplemented --- 
271:   */
272: #else
273:   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
274: #endif

276:   *value = *((void**)&dlsymbol);

278:   return(0);
279: }