mx/dynlink.h API.

This commit is contained in:
H. Utku Maden 2023-09-10 20:44:54 +03:00
parent 2751a98e33
commit b19f8d1305
Signed by: themixedupstuff
GPG Key ID: 25A001B636F17843
3 changed files with 109 additions and 0 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