From 2751a98e33a4fa8cd2602b4d03cb81ebf68a83a1 Mon Sep 17 00:00:00 2001 From: "H. Utku Maden" Date: Sat, 9 Sep 2023 21:50:56 +0300 Subject: [PATCH 1/2] Fix typo that copied argv to argc. --- src/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/options.c b/src/options.c index 95fdad4..c4ce357 100644 --- a/src/options.c +++ b/src/options.c @@ -24,7 +24,7 @@ MX_IMPL void mx_options_begin_r(mx_options_t *self, mx_optflag_t flags, int argc MX_ASSERT(argc > 0, "Arguments count must be greater than zero."); self->flags = flags; - self->argc = argv; + self->argv = argv; self->argc = argc; self->i = 0; self->kind = MX_OPT_END; From b19f8d13052907b779310b27e9b091738a23aeb0 Mon Sep 17 00:00:00 2001 From: "H. Utku Maden" Date: Sun, 10 Sep 2023 20:44:54 +0300 Subject: [PATCH 2/2] mx/dynlink.h API. --- include/mx/dynlink.h | 40 ++++++++++++++++++++++++++++++++++++++++ src/dynlink.unix.c | 36 ++++++++++++++++++++++++++++++++++++ src/dynlink.win32.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 include/mx/dynlink.h create mode 100644 src/dynlink.unix.c create mode 100644 src/dynlink.win32.c diff --git a/include/mx/dynlink.h b/include/mx/dynlink.h new file mode 100644 index 0000000..adb4f80 --- /dev/null +++ b/include/mx/dynlink.h @@ -0,0 +1,40 @@ +#ifndef _MX_DYNLINK_H_ +#define _MX_DYNLINK_H_ +/** + * @file dynlink.h LibMX Dynamic Linker + * + * The LibMX dynamic linker is intended to wrap over the native operating system + * functionalities normally provided by their respective user libraries. + * Internally dlfunc (*NIX) or LoadLibrary (Win32) is used. + */ + +#include "mx/base.h" + +/** Handle to module. */ +typedef void *mx_lib_t; + +/** Handle to own module. */ +#define MX_LIB_SELF ((mx_lib_t)~0ll) + +/** + * Open a library. + * @param[in] name The name of the library. + * @return Handle to the library. Check against NULL. + */ +MX_API mx_lib_t mx_lib_open(const char *name); + +/** + * Close an already open library. + * @param[in] lib The library to close. + */ +MX_API void mx_lib_close(mx_lib_t lib); + +/** + * Get the address of a symbol. (a global variable or function.) + * @param[in] lib The library to look up. + * @param[in] symbol The name of the symbol to look up. + * @return Address to the storage location for the symbol. + */ +MX_API void *mx_lib_get_symbol(mx_lib_t lib, const char *symbol); + +#endif \ No newline at end of file diff --git a/src/dynlink.unix.c b/src/dynlink.unix.c new file mode 100644 index 0000000..ebdfe5a --- /dev/null +++ b/src/dynlink.unix.c @@ -0,0 +1,36 @@ +#if __unix__ +#include "mx/dynlink.h" +#include "mx/assert.h" +#include "dlfcn.h" + +#ifdef DEBUG + #define RTLD_DEFAULT (RTLD_NOW) +#else + #define RTLD_DEFAULT (RTLD_LAZY) +#endif + +MX_IMPL mx_lib_t mx_lib_open(const char *name) +{ + void *plib = dlopen(name, RTLD_DEFAULT); + return (mx_lib_t)plib; +} + +MX_IMPL void mx_lib_close(mx_lib_t lib) +{ + MX_ASSERT_PTR(lib, "The library must be open."); + MX_ASSERT(lib != MX_LIB_SELF, "You cannot close this module."); + + dlclose((void*)lib); +} + +MX_IMPL void *mx_lib_get_symbol(mx_lib_t lib, const char *symbol) +{ + MX_ASSERT_PTR(lib, "The library must be open."); + + /* The self library pointer is NULL for dlfunc. */ + if (lib == MX_LIB_SELF) lib = NULL; + + return dlsym((void*)lib, symbol); +} + +#endif diff --git a/src/dynlink.win32.c b/src/dynlink.win32.c new file mode 100644 index 0000000..109f1ab --- /dev/null +++ b/src/dynlink.win32.c @@ -0,0 +1,33 @@ +#if _WIN32 +#include "mx/dynlink.h" +#include "mx/assert.h" +#include "windows.h" + +MX_IMPL mx_lib_t mx_lib_open(const char *name) +{ + HMODULE lib = LoadLibrary(name); + return (mx_lib_t)lib; +} + +MX_IMPL void mx_lib_close(mx_lib_t lib) +{ + MX_ASSERT_PTR(lib, "The library must be open."); + MX_ASSERT(lib != MX_LIB_SELF, "You cannot close this module."); + + FreeLibrary((HMODULE)lib); +} + +MX_IMPL void *mx_lib_get_symbol(mx_lib_t lib, const char *symbol) +{ + MX_ASSERT_PTR(lib, "The library must be open."); + + /* The self library pointer is retreived with GetModuleHandle. */ + if (lib == MX_LIB_SELF) + { + lib = (mx_lib_t)GetModuleHandle(NULL); + } + + return GetProcAddress((HMODULE)lib, symbol); +} + +#endif