From 435cf35bcc28ab4220764dff7874f477310d9a48 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aur=C3=A9lien=20Aptel?= Date: Mon, 16 Nov 2015 00:36:35 +0100 Subject: [PATCH] Add portable layer for dynamic loading * src/dynlib.h: New file. * src/dynlib.c: New file. Co-authored-by: Philipp Stephani --- src/dynlib.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dynlib.h | 14 ++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/dynlib.c create mode 100644 src/dynlib.h 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 */ -- 2.39.5