From b8c82b20f93b94aa976cfe48ebed4df7325a65a6 Mon Sep 17 00:00:00 2001 From: nishi Date: Sat, 27 Apr 2024 04:54:17 +0000 Subject: [PATCH] binmod works git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@74 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- Serenade/binmodule.c | 57 +++++++++++++++++++++++++++++++++++++++++++- Serenade/binmodule.h | 6 +++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Serenade/binmodule.c b/Serenade/binmodule.c index 9e0413c..f388de5 100644 --- a/Serenade/binmodule.c +++ b/Serenade/binmodule.c @@ -31,6 +31,7 @@ #include "binmodule.h" #include "interpreter.h" +#include "util.h" #ifdef __MINGW32__ #include @@ -38,9 +39,63 @@ #include #endif -void binmodule_init(struct sn_interpreter* sn){ +#include +#include +#include + +struct sn_generic* binmodule_load_handler(struct sn_interpreter* sn, int argc, struct sn_generic** args) { + struct sn_generic* gen = malloc(sizeof(struct sn_generic)); + gen->type = SN_TYPE_DOUBLE; + gen->number = -1; + void* lib = NULL; + char* name = sn_strdup("module"); + if((argc == 3 || argc == 2) && args[1]->type == SN_TYPE_STRING) { + if((argc == 3 ? (args[2]->type == SN_TYPE_STRING) : true)) { + char* path = malloc(args[1]->string_length + 1); + memcpy(path, args[1]->string, args[1]->string_length); + path[args[1]->string_length] = 0; +#ifdef __MINGW32__ + lib = LoadLibraryA(path); +#else + lib = dlopen(path, RTLD_LAZY); +#endif + free(path); + if(argc == 3) { + free(name); + name = malloc(args[2]->string_length + 1); + memcpy(name, args[2]->string, args[2]->string_length); + name[args[2]->string_length] = 0; + } + } + } + if(lib != NULL) { + struct sn_binmodule_config* conf = malloc(sizeof(struct sn_binmodule_config)); + conf->interpreter = sn; + conf->set_variable = sn_set_variable; + conf->set_handler = sn_set_handler; + char* symbol_name = sn_strcat(name, "_init"); + int (*loadfunc)(struct sn_binmodule_config*); +#ifdef __MINGW32__ + loadfunc = (int (*)(struct sn_binmodule_config*))GetProcAddress(lib, symbol_name); +#else + loadfunc = (int (*)(struct sn_binmodule_config*))dlsym(lib, symbol_name); +#endif + if(loadfunc == NULL) { + gen->number = -1; + } else { + gen->number = loadfunc(conf); + } + free(symbol_name); + free(conf); + } + free(name); + return gen; +} + +void binmodule_init(struct sn_interpreter* sn) { struct sn_generic* gen = malloc(sizeof(struct sn_generic)); gen->type = SN_TYPE_DOUBLE; gen->number = 1; sn_set_variable(sn, "binmodule-loaded", gen); + sn_set_handler(sn, "binmodule-load", binmodule_load_handler); } diff --git a/Serenade/binmodule.h b/Serenade/binmodule.h index 41c0b4a..49b9ebc 100644 --- a/Serenade/binmodule.h +++ b/Serenade/binmodule.h @@ -35,4 +35,10 @@ void binmodule_init(struct sn_interpreter* sn); +struct sn_binmodule_config { + struct sn_interpreter* interpreter; + struct sn_interpreter_kv* (*set_variable)(struct sn_interpreter* sn, const char* name, struct sn_generic* gen); + struct sn_interpreter_kv* (*set_handler)(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)); +}; + #endif -- 2.43.0