From: Aurélien Aptel Date: Sun, 15 Nov 2015 23:36:35 +0000 (+0100) Subject: Add portable layer for dynamic loading X-Git-Tag: emacs-25.0.90~750 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=435cf35bcc28ab4220764dff7874f477310d9a48;p=emacs.git Add portable layer for dynamic loading * src/dynlib.h: New file. * src/dynlib.c: New file. Co-authored-by: Philipp Stephani --- diff --git a/src/dynlib.c b/src/dynlib.c new file mode 100644 index 00000000000..f9478099169 --- /dev/null +++ b/src/dynlib.c @@ -0,0 +1,93 @@ +/* + * Portable API for dynamic loading + * + * Assuming modules are enabled on modern systems... *Yes*, the + * preprocessor macro checks could be more precise. I don't care. + * + * If you think the abstraction is too leaky use libltdl (libtool), + * don't reinvent the wheel by fixing this one. + */ + +#include "dynlib.h" + +/* + * Windows systems + */ +#if defined(_WIN32) + +#include + +dynlib_handle_ptr dynlib_open (const char * path) +{ + + return (dynlib_handle_ptr) LoadLibrary (path); +} + +void * dynlib_sym (dynlib_handle_ptr h, const char * sym) +{ + return GetProcAddress ((HMODULE) h, sym); +} + +bool dynlib_addr (void *ptr, const char **path, const char **sym) +{ + return false; /* not implemented */ +} + +const char * dynlib_error (void) +{ + /* TODO: use GetLastError(), FormatMessage(), ... */ + return "Can't load DLL"; +} + +int dynlib_close (dynlib_handle_ptr h) +{ + return FreeLibrary ((HMODULE) h) != 0; +} + + +/* + * POSIX systems + */ +#elif defined(HAVE_UNISTD_H) + +#include + +dynlib_handle_ptr dynlib_open (const char * path) +{ + return dlopen (path, RTLD_LAZY); +} + +void * dynlib_sym (dynlib_handle_ptr h, const char * sym) +{ + return dlsym (h, sym); +} + +bool dynlib_addr (void *ptr, const char **path, const char **sym) +{ +#ifdef HAVE_DLADDR + Dl_info info; + if (dladdr (ptr, &info) != 0 && info.dli_fname != NULL && info.dli_sname != NULL) + { + *path = info.dli_fname; + *sym = info.dli_sname; + return true; + } +#endif + return false; +} + +const char * dynlib_error (void) +{ + return dlerror (); +} + +int dynlib_close (dynlib_handle_ptr h) +{ + return dlclose (h) == 0; +} + +#else + +#error "No dynamic loading for this system" + +#endif diff --git a/src/dynlib.h b/src/dynlib.h new file mode 100644 index 00000000000..229fc960221 --- /dev/null +++ b/src/dynlib.h @@ -0,0 +1,14 @@ +#ifndef DYNLIB_H +#define DYNLIB_H + +#include +#include + +typedef void* dynlib_handle_ptr; +dynlib_handle_ptr dynlib_open (const char * path); +void * dynlib_sym (dynlib_handle_ptr h, const char * sym); +bool dynlib_addr (void *ptr, const char **path, const char **sym); +const char * dynlib_error (void); +int dynlib_close (dynlib_handle_ptr h); + +#endif /* DYNLIB_H */