Added SILC DLL API for loading/using shared objects/DLLs.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 3 Jul 2007 19:44:23 +0000 (19:44 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 3 Jul 2007 19:44:23 +0000 (19:44 +0000)
lib/silcutil/silcdll.c [new file with mode: 0644]
lib/silcutil/silcdll.h [new file with mode: 0644]
lib/silcutil/tests/test_silcdll.c [new file with mode: 0644]

diff --git a/lib/silcutil/silcdll.c b/lib/silcutil/silcdll.c
new file mode 100644 (file)
index 0000000..20acef0
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+
+  silcdll.c
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2007 Pekka Riikonen
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+
+/* Load shared object */
+
+SilcDll silc_dll_load(const char *object_path)
+{
+#ifdef SILC_UNIX
+#if defined(HAVE_DLOPEN)
+#if defined(RTLD_NOW)
+  return dlopen(object_path, RTLD_NOW);
+#elif defined(RTLD_LAZY)
+  return dlopen(object_path, RTLD_LAZY);
+#else
+  return dlopen(object_path, 0);
+#endif /* RTLD_NOW */
+#endif /* HAVE_DLOPEN */
+#elif SILC_WIN32
+  return LoadLibrary(object_path);
+#else
+  /* XXX Symbian */
+#endif /* SILC_UNIX */
+  SILC_LOG_ERROR(("Shared objects are not supported on this platform"));
+  return NULL;
+}
+
+/* Close shared object */
+
+void silc_dll_close(SilcDll dll)
+{
+#ifdef SILC_UNIX
+  dlclose(dll);
+#elif SILC_WIN32
+  FreeLibrary(dll);
+#else
+  /* XXX Symbian */
+#endif /* SILC_UNIX */
+}
+
+/* Get symbol address from shared object */
+
+void *silc_dll_getsym(SilcDll dll, const char *symbol)
+{
+#ifdef SILC_UNIX
+  return (void *)dlsym(dll, symbol);
+#elif SILC_WIN32
+  return (void *)GetProcAddress(dll, symbol);
+#else
+  /* XXX Symbian */
+#endif /* SILC_UNIX */
+  SILC_LOG_ERROR(("Shared objects are not supported on this platform"));
+  return NULL;
+}
+
+/* Get error string */
+
+const char *silc_dll_error(SilcDll dll)
+{
+#ifdef SILC_UNIX
+  return dlerror();
+#elif SILC_WIN32
+  return NULL;
+#else
+  /* XXX Symbian */
+#endif /* SILC_UNIX */
+  return NULL;
+}
diff --git a/lib/silcutil/silcdll.h b/lib/silcutil/silcdll.h
new file mode 100644 (file)
index 0000000..3da325b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+
+  silcdll.h
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2007 Pekka Riikonen
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+/****h* silcutil/Shared Object Interface
+ *
+ * DESCRIPTION
+ *
+ * Platform independent iterface for loading and using shared objects and
+ * dynamically linked libraries (DLLs).
+ *
+ ***/
+
+#ifndef SILCDLL_H
+#define SILCDLL_H
+
+/****s* silcutil/SilcDLLAPI/SilcDll
+ *
+ * NAME
+ *
+ *    typedef void *SilcDll;
+ *
+ * DESCRIPTION
+ *
+ *    This context represents the shared object and it is allocated by
+ *    silc_dll_load and is destroyed with silc_dll_close functions.
+ *    The context is given as argument to all funtions in this interface.
+ *
+ ***/
+#ifdef SILC_UNIX
+typedef void *SilcDll;
+#elif SILC_WIN32
+typedef HMODULE SilcDll;
+#else
+typedef void *SilcDll;
+#endif /* SILC_UNIX */
+
+/****f* silcutil/SilcDLLAPI/silc_dll_load
+ *
+ * SYNOPSIS
+ *
+ *    SilcDll silc_dll_load(const char *object_path);
+ *
+ * DESCRIPTION
+ *
+ *    Load shared object or DLL indicated by the `object_path'.  The path
+ *    must include the absolute path to the object and the object name.
+ *    Returns the SilcDll context or NULL on error.  The actual error
+ *    message may be available by calling silc_dll_error function.  Symbols
+ *    may be retrieved from the returned context by calling silc_dll_getsym.
+ *
+ ***/
+SilcDll silc_dll_load(const char *object_path);
+
+/****f* silcutil/SilcDLLAPI/silc_dll_close
+ *
+ * SYNOPSIS
+ *
+ *    void silc_dll_close(SilcDll dll);
+ *
+ * DESCRIPTION
+ *
+ *    Closes the shared object indicated by `dll'.  Any symbol retrieved
+ *    from the `dll' with silc_dll_getsym will become invalid and cannot
+ *    be used anymore.
+ *
+ ***/
+void silc_dll_close(SilcDll dll);
+
+/****f* silcutil/SilcDLLAPI/silc_dll_getsym
+ *
+ * SYNOPSIS
+ *
+ *    void *silc_dll_getsym(SilcDll dll, const char *symbol);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the memory address of the symbol indicated by `symbol' from
+ *    the shared object indicated by `dll'.  If such symbol does not exist
+ *    this returns NULL.
+ *
+ ***/
+void *silc_dll_getsym(SilcDll dll, const char *symbol);
+
+/****f* silcutil/SilcDLLAPI/silc_dll_error
+ *
+ * SYNOPSIS
+ *
+ *    const char *silc_dll_error(SilcDll dll);
+ *
+ * DESCRIPTION
+ *
+ *    This routine may return error string after an error has occured with
+ *    the shared object indicated by `dll'.  If error string is not available
+ *    this will return NULL.
+ *
+ ***/
+const char *silc_dll_error(SilcDll dll);
+
+#endif /* SILCDLL_H */
diff --git a/lib/silcutil/tests/test_silcdll.c b/lib/silcutil/tests/test_silcdll.c
new file mode 100644 (file)
index 0000000..00cf270
--- /dev/null
@@ -0,0 +1,41 @@
+/* SilcDll tests */
+
+#include "silc.h"
+
+int main(int argc, char **argv)
+{
+  SilcBool success = FALSE;
+  SilcDll dll;
+  void *ptr;
+
+  if (argc > 1 && !strcmp(argv[1], "-d")) {
+    silc_log_debug(TRUE);
+    silc_log_quick(TRUE);
+    silc_log_debug_hexdump(TRUE);
+    silc_log_set_debug_string("*dll*");
+  }
+
+  SILC_LOG_DEBUG(("Load shared object /lib/libc.so.6"));
+  dll = silc_dll_load("/lib/libc.so.6");
+  if (!dll) {
+    SILC_LOG_DEBUG(("Cannot load: %s", silc_dll_error(dll)));
+    goto err;
+  }
+
+  SILC_LOG_DEBUG(("Get symbol 'fprintf'"));
+  ptr = silc_dll_getsym(dll, "fprintf");
+  if (!ptr)
+    goto err;
+  SILC_LOG_DEBUG(("Symbol address %p", ptr));
+
+  SILC_LOG_DEBUG(("Close shared object"));
+  silc_dll_close(dll);
+
+  success = TRUE;
+
+ err:
+  SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
+  fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
+
+  return success;
+}