Merge branch 'master' of github.com:utkumaden/libmx

This commit is contained in:
H. Utku Maden 2023-12-01 22:36:51 +03:00
commit 6c444ddc08
Signed by: themixedupstuff
GPG Key ID: 25A001B636F17843
4 changed files with 110 additions and 1 deletions

40
include/mx/dynlink.h Normal file

@ -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

36
src/dynlink.unix.c Normal file

@ -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

33
src/dynlink.win32.c Normal file

@ -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

@ -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;