#include "stk.h" #include #include void *platform_load_library(const char *path); void platform_unload_library(void *handle); void *platform_get_symbol(void *handle, const char *symbol); typedef void (*stk_module_func)(void); static char **stk_module_ids = NULL; static void **stk_handles = NULL; static stk_module_func *stk_inits = NULL; static stk_module_func *stk_shutdowns = NULL; size_t module_count = 0; size_t stk_module_count(void) { return module_count; } static char *extract_module_id(const char *path) { char *id, *dot; const char *basename = strrchr(path, '/'); if (!basename) basename = path; else basename++; id = malloc(strlen(basename) + 1); strcpy(id, basename); dot = strrchr(id, '.'); if (dot) *dot = '\0'; return id; } int stk_module_load(const char *path) { void *handle; stk_module_func init_func; stk_module_func shutdown_func; handle = platform_load_library(path); if (!handle) return -1; init_func = (stk_module_func)platform_get_symbol(handle, "stk_module_init"); shutdown_func = (stk_module_func)platform_get_symbol(handle, "stk_module_shutdown"); if (!init_func || !shutdown_func) { platform_unload_library(handle); return -2; } stk_module_ids[module_count] = extract_module_id(path); stk_handles[module_count] = handle; stk_inits[module_count] = init_func; stk_shutdowns[module_count] = shutdown_func; init_func(); ++module_count; return 0; } void stk_module_unload(size_t index) { size_t i; stk_shutdowns[index](); platform_unload_library(stk_handles[index]); for (i = index; i < module_count - 1; ++i) { stk_module_ids[i] = stk_module_ids[i + 1]; stk_handles[i] = stk_handles[i + 1]; stk_inits[i] = stk_inits[i + 1]; stk_shutdowns[i] = stk_shutdowns[i + 1]; } --module_count; } void stk_module_free_memory(void) { free(stk_module_ids); free(stk_handles); free(stk_inits); free(stk_shutdowns); stk_module_ids = NULL; stk_handles = NULL; stk_inits = NULL; stk_shutdowns = NULL; } int stk_module_init_memory(size_t capacity) { stk_module_ids = malloc(capacity * sizeof(char *)); stk_handles = malloc(capacity * sizeof(void *)); stk_inits = malloc(capacity * sizeof(stk_module_func)); stk_shutdowns = malloc(capacity * sizeof(stk_module_func)); if (!stk_handles || !stk_inits || !stk_shutdowns) { stk_module_free_memory(); return -1; } return 0; } void stk_module_unload_all(void) { size_t i; for (i = module_count; i > 0; --i) stk_module_unload(i - 1); stk_module_free_memory(); }