summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2010-05-18 18:25:41 +0200
committerAndreas Baumann <abaumann@yahoo.com>2010-05-18 18:25:41 +0200
commit686ee56fc5e4b8a3573dbad3a0e997fe89ba71a7 (patch)
tree91617a193bebb5a7d2946a065d71562c9cf530ba
parent9d6b4ab6fee3d65f3a11a5f19c410e5abe4ba322 (diff)
downloadwolfbones-686ee56fc5e4b8a3573dbad3a0e997fe89ba71a7.tar.gz
wolfbones-686ee56fc5e4b8a3573dbad3a0e997fe89ba71a7.tar.bz2
now stuck in dlsym/dereferencing type-punned pointer will break strict-aliasing rules beautiness :-)
-rw-r--r--include/wolf/library/loader.h14
-rw-r--r--src/library/loader.c14
-rw-r--r--tests/library/test_loader.c20
3 files changed, 44 insertions, 4 deletions
diff --git a/include/wolf/library/loader.h b/include/wolf/library/loader.h
index a2ee16e..2218677 100644
--- a/include/wolf/library/loader.h
+++ b/include/wolf/library/loader.h
@@ -70,10 +70,22 @@ wolf_error_t wolf_library_unload( wolf_library_p library );
* @param buf the buffer which will hold the error message
* @param buflen the size of the buffer
*
- * @returns a pointer to buf for convenience
+ * @return a pointer to buf for convenience
*/
char *wolf_library_errmsg( const wolf_error_t error, const wolf_library_p library, char *buf, size_t buflen );
+/**
+ * Gets a symbol (usually a function) from the library object. It has to be
+ * casted properly to the function you are expecting to call.
+ *
+ * @param library the library object
+ * @param name name of the symbol to retrieve
+ * @param error WOLF_OK if the symbol could be loaded
+ *
+ * @return a pointer to the retrieved symbol
+ */
+void *wolf_library_get( const wolf_library_p library, const char *name, wolf_error_t *error );
+
/** @} */ /* @addtogroup wolf_library */
#endif /* ifndef WOLF_LOADER_H */
diff --git a/src/library/loader.c b/src/library/loader.c
index ad83bda..cf5f0e3 100644
--- a/src/library/loader.c
+++ b/src/library/loader.c
@@ -85,12 +85,22 @@ wolf_error_t wolf_library_unload( wolf_library_p l ) {
return WOLF_OK;
}
-char *wolf_library_errmsg( const wolf_error_t error, const wolf_library_p l, char *buf, size_t buflen ) {
+char *wolf_library_errmsg( const wolf_error_t error, const wolf_library_p library, char *buf, size_t buflen ) {
(void)wolf_error_msg( error, buf, buflen );
strncat( buf, " - ", buflen - strlen( buf ) );
if( error == WOLF_ERR_INTERNAL ) {
- strncat( buf, l->errbuf, buflen - strlen( buf ) );
+ strncat( buf, library->errbuf, buflen - strlen( buf ) );
}
return buf;
}
+
+void *wolf_library_get( const wolf_library_p l, const char *name, wolf_error_t *error ) {
+ void *ret;
+
+ ret = dlsym( l->handle, name );
+
+ *error = WOLF_OK;
+ return ret;
+}
+
diff --git a/tests/library/test_loader.c b/tests/library/test_loader.c
index 6088c92..b9bce9d 100644
--- a/tests/library/test_loader.c
+++ b/tests/library/test_loader.c
@@ -19,12 +19,17 @@
#include <stdlib.h> /* for EXIT_SUCCESS, EXIT_FAILURE */
#include <stdio.h> /* for fprintf */
+#include <assert.h> /* for assert */
int main( void ) {
wolf_library_p library;
wolf_error_t error;
char errbuf[512];
+ typedef int (*multiply_by_two_func)( int );
+ multiply_by_two_func func;
+ int res = 0;
+ /* open the libray */
library = wolf_library_load( "./testlib.so.0.0.0", &error );
if( error != WOLF_OK ) {
fprintf( stderr, "Error %d loading the library: %s\n",
@@ -32,7 +37,20 @@ int main( void ) {
return EXIT_FAILURE;
}
- wolf_library_unload( library );
+ /* fetch a known symbol (multiply_by_two) */
+ *(void **)(&func) = wolf_library_get( library, "multiply_by_two", &error );
+
+ /* call it */
+ res = func( 2 );
+ assert( res == 4 );
+
+ /* close library */
+ error = wolf_library_unload( library );
+ if( error != WOLF_OK ) {
+ fprintf( stderr, "Error %d unloading the library: %s\n",
+ error, wolf_library_errmsg( error, library, errbuf, 512 ) );
+ return EXIT_FAILURE;
+ }
return EXIT_SUCCESS;
}