From 3204613c6f1f0db36e104c078d8cd01e12a8d9b6 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 4 Jul 2026 15:33:40 +1000 Subject: [PATCH] Wrap dlopen/dlsym --- include/ground.h | 19 ++++++++++++++++ meson.build | 3 +++ src/FFI/getFunction.c | 22 +++++++++++++++++++ src/FFI/openSharedObject.c | 45 ++++++++++++++++++++++++++++++++++++++ src/libmain.c | 8 +++++++ 5 files changed, 97 insertions(+) create mode 100644 src/FFI/getFunction.c create mode 100644 src/FFI/openSharedObject.c diff --git a/include/ground.h b/include/ground.h index 21b0b4e..53324e0 100644 --- a/include/ground.h +++ b/include/ground.h @@ -7,6 +7,14 @@ #include #include +#ifdef _WIN32 +// TODO: check if this works +#include +#define PATH_MAX MAX_PATH +#else +#include +#endif + // // TYPES // @@ -352,6 +360,11 @@ struct GroundExecutionResult { } as; }; +struct GroundOpenSharedObjects { + char path[PATH_MAX]; + void* handle; + UT_hash_handle hh; +}; // // INTERFACE @@ -522,6 +535,12 @@ struct _Ground { char* (*BytecodeValue)(GroundBytecodeValue* value); } Stringify; + + struct { + struct GroundOpenSharedObjects* objects; + void* (*openSharedObject)(char* id); + void* (*getFunction)(void* handle, char* id); + } FFI; }; extern struct _Ground Ground; diff --git a/meson.build b/meson.build index 29c92c7..069ab11 100644 --- a/meson.build +++ b/meson.build @@ -27,6 +27,9 @@ sources = files( 'src/Copy/BytecodeValue.c', + 'src/FFI/openSharedObject.c', + 'src/FFI/getFunction.c', + 'src/Free/Function.c', 'src/Free/List.c', 'src/Free/Object.c', diff --git a/src/FFI/getFunction.c b/src/FFI/getFunction.c new file mode 100644 index 0000000..514f5d6 --- /dev/null +++ b/src/FFI/getFunction.c @@ -0,0 +1,22 @@ +#include "../../include/ground.h" + +#ifdef _WIN32 +// TODO: Windows support +#else +#include +#endif + +void* _GroundFFIGetFunction(void* handle, char* id) { +#ifdef _WIN32 + // TODO: Windows support +#else + void* function = dlsym(handle, id); + char* error = dlerror(); + if (error != NULL) { + Ground.Log.Error(error); + Ground.Flags.error = true; + return NULL; + } + return function; +#endif +} diff --git a/src/FFI/openSharedObject.c b/src/FFI/openSharedObject.c new file mode 100644 index 0000000..0793280 --- /dev/null +++ b/src/FFI/openSharedObject.c @@ -0,0 +1,45 @@ +#include "../../include/ground.h" + +#include + +#ifdef _WIN32 +// TODO: Windows support +#else +#include +#endif + +void* _GroundFFIOpenSharedObject(char* id) { + + struct GroundOpenSharedObjects* object = NULL; + HASH_FIND_STR(Ground.FFI.objects, id, object); + + if (object != NULL) { + return object->handle; + } + + void* handle = NULL; + +#ifdef _WIN32 + // TODO: Windows support +#else + // Assume POSIX platform + handle = dlopen(id, RTLD_LAZY); + if (handle == NULL) { + Ground.Log.Error(dlerror()); + Ground.Flags.error = true; + return NULL; + } + +#endif + + object = malloc(sizeof(struct GroundOpenSharedObjects)); + if (object == NULL) { + Ground.Log.Error("malloc failed in Ground.FFI.openSharedObject"); + Ground.Flags.error = true; + return NULL; + } + object->handle = handle; + snprintf(object->path, sizeof(object->path), "%s", id); + HASH_ADD_STR(Ground.FFI.objects, path, object); + return handle; +} diff --git a/src/libmain.c b/src/libmain.c index 5437172..f13241d 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -122,6 +122,8 @@ char* _GroundStringifyValue(GroundValue* value); char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value); +void* _GroundFFIOpenSharedObject(char* id); +void* _GroundFFIGetFunction(void* handle, char* id); struct _Ground Ground = { @@ -273,4 +275,10 @@ struct _Ground Ground = { .BytecodeValue = _GroundStringifyBytecodeValue, }, + + .FFI = { + .objects = NULL, + .openSharedObject = _GroundFFIOpenSharedObject, + .getFunction = _GroundFFIGetFunction, + }, };