commit b2fa0ba1c747b60e3c519d494b750488ce60fe92
parent 0566b8f493dd227135d1102403999fccef3683ce
Author: vaplv <vaplv@free.fr>
Date: Mon, 11 Nov 2013 16:17:41 +0100
Add dynamic library loading
Diffstat:
4 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -28,12 +28,14 @@ add_definitions(-D_POSIX_C_SOURCE=200112L)
set(RSYS_FILES_SRC
clock_time.c
image.c
+ library.c
mem_allocator.c)
set(RSYS_FILES_INC
atomic.h
clock_time.h
image.h
+ library.h
list.h
mem_allocator.h
ref_count.h
@@ -41,11 +43,16 @@ set(RSYS_FILES_INC
rsys.h)
add_library(rsys SHARED ${RSYS_FILES_SRC} ${RSYS_FILES_INC})
+target_link_libraries(rsys dl)
set_target_properties(rsys PROPERTIES DEFINE_SYMBOL RSYS_SHARED_BUILD)
################################################################################
# Add tests
################################################################################
+add_executable(test_library test_library.c)
+target_link_libraries(test_library rsys)
+add_test(test_library test_library)
+
add_executable(test_list test_list.c)
target_link_libraries(test_list rsys)
add_test(test_list test_list)
diff --git a/src/library.c b/src/library.c
@@ -0,0 +1,48 @@
+#include "library.h"
+#include <dlfcn.h>
+#include <stdio.h>
+
+void*
+library_open(const char* filename)
+{
+ if(!filename)
+ return NULL;
+
+ void* handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL);
+ if(!handle) {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ return handle;
+}
+
+void*
+library_get_symbol(void* lib, const char* sym)
+{
+ if(!lib || !sym)
+ return NULL;
+
+ void* tmp_sym = dlsym(lib, sym);
+ char* err = dlerror();
+ if(err == NULL) {
+ return tmp_sym;
+ } else {
+ fprintf(stderr, "%s\n", err);
+ return NULL;
+ }
+}
+
+int
+library_close(void* handle)
+{
+ if(!handle)
+ return -1;
+
+ const int err = dlclose(handle);
+ if(err) {
+ fprintf(stderr, "%s\n", dlerror());
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/src/library.h b/src/library.h
@@ -0,0 +1,32 @@
+#ifndef LIBRARY_H
+#define LIBRARY_H
+
+#include "rsys.h"
+
+#ifdef PLATFORM_UNIX
+ #define SHARED_LIBRARY_NAME(Lib) "lib"Lib".so"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+RSYS_API void* /* Library handle */
+library_open
+ (const char* filename);
+
+RSYS_API void*
+library_get_symbol
+ (void* lib,
+ const char* symbol);
+
+RSYS_API int
+library_close
+ (void* handle);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LIBRARY_H */
+
diff --git a/src/test_library.c b/src/test_library.c
@@ -0,0 +1,24 @@
+#include "library.h"
+#include "mem_allocator.h"
+
+int
+main(int argc, char** argv)
+{
+ void* lib = NULL;
+ (void)argc, (void)argv;
+
+ CHECK(library_open(NULL), NULL);
+ CHECK(library_open("none"), NULL);
+ lib = library_open("./" SHARED_LIBRARY_NAME("rsys"));
+ NCHECK(lib, NULL);
+
+ CHECK(library_get_symbol(lib, "library_get_SYMBOL"), NULL);
+ NCHECK(library_get_symbol(lib, "library_get_symbol"), NULL);
+
+ NCHECK(library_close(NULL), 0);
+ CHECK(library_close(lib), 0);
+
+ CHECK(MEM_ALLOCATED_SIZE(&mem_default_allocator), 0);
+
+ return 0;
+}