summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-09-27 16:16:15 +0200
committerDavid Robillard <d@drobilla.net>2020-09-27 16:16:15 +0200
commite5345ab3e4bad3ee929c0f08a9161b46fa6e2071 (patch)
treea2b5d9b32f3643e2a301680a1ef6f750d0993c0a
parent0ab07d65fe9261ecfa495090691db324eff7aefc (diff)
downloadsuil-e5345ab3e4bad3ee929c0f08a9161b46fa6e2071.tar.gz
suil-e5345ab3e4bad3ee929c0f08a9161b46fa6e2071.tar.bz2
suil-e5345ab3e4bad3ee929c0f08a9161b46fa6e2071.zip
Add a less janky portability wrapper for dlopen() and friends
-rw-r--r--src/dylib.h78
-rw-r--r--src/gtk2_in_qt4.cpp7
-rw-r--r--src/gtk2_in_qt5.cpp8
-rw-r--r--src/host.c6
-rw-r--r--src/instance.c20
-rw-r--r--src/suil_internal.h18
6 files changed, 103 insertions, 34 deletions
diff --git a/src/dylib.h b/src/dylib.h
new file mode 100644
index 0000000..246693c
--- /dev/null
+++ b/src/dylib.h
@@ -0,0 +1,78 @@
+/*
+ Copyright 2020 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef SUIL_DYLIB_H
+#define SUIL_DYLIB_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+enum DylibFlags {
+ DYLIB_GLOBAL = 0,
+ DYLIB_LAZY = 1,
+ DYLIB_NOW = 2,
+};
+
+static inline void*
+dylib_open(const char* const filename, const int flags)
+{
+ return LoadLibrary(filename);
+}
+
+static inline int
+dylib_close(void* const handle)
+{
+ return !FreeLibrary((HMODULE)handle);
+}
+
+static inline const char*
+dylib_error(void)
+{
+ return "Unknown error";
+}
+
+#else
+
+#include <dlfcn.h>
+
+enum DylibFlags {
+ DYLIB_GLOBAL = RTLD_GLOBAL,
+ DYLIB_LAZY = RTLD_LAZY,
+ DYLIB_NOW = RTLD_NOW,
+};
+
+static inline void*
+dylib_open(const char* const filename, const int flags)
+{
+ return dlopen(filename, flags);
+}
+
+static inline int
+dylib_close(void* const handle)
+{
+ return dlclose(handle);
+}
+
+static inline const char*
+dylib_error(void)
+{
+ return dlerror();
+}
+
+#endif
+
+#endif // SUIL_DYLIB_H
diff --git a/src/gtk2_in_qt4.cpp b/src/gtk2_in_qt4.cpp
index 91b374c..3e2e256 100644
--- a/src/gtk2_in_qt4.cpp
+++ b/src/gtk2_in_qt4.cpp
@@ -14,6 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "dylib.h"
#include "suil_config.h"
#include "suil_internal.h"
@@ -116,11 +117,11 @@ suil_wrapper_new(SuilHost* host,
type" errors.
*/
if (!host->gtk_lib) {
- dlerror();
- host->gtk_lib = dlopen(SUIL_GTK2_LIB_NAME, RTLD_LAZY|RTLD_GLOBAL);
+ dylib_error();
+ host->gtk_lib = dylib_open(SUIL_GTK2_LIB_NAME, DYLIB_LAZY|DYLIB_GLOBAL);
if (!host->gtk_lib) {
SUIL_ERRORF("Failed to open %s (%s)\n",
- SUIL_GTK2_LIB_NAME, dlerror());
+ SUIL_GTK2_LIB_NAME, dylib_error());
return NULL;
}
gtk_init(NULL, NULL);
diff --git a/src/gtk2_in_qt5.cpp b/src/gtk2_in_qt5.cpp
index c4add29..f6bf48e 100644
--- a/src/gtk2_in_qt5.cpp
+++ b/src/gtk2_in_qt5.cpp
@@ -15,6 +15,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "dylib.h"
#include "suil_config.h"
#include "suil_internal.h"
@@ -35,7 +36,6 @@
#include <gtk/gtk.h>
#include <gobject/gclosure.h>
-#include <dlfcn.h>
#include <stdlib.h>
extern "C" {
@@ -138,11 +138,11 @@ suil_wrapper_new(SuilHost* host,
type" errors.
*/
if (!host->gtk_lib) {
- dlerror();
- host->gtk_lib = dlopen(SUIL_GTK2_LIB_NAME, RTLD_LAZY|RTLD_GLOBAL);
+ dylib_error();
+ host->gtk_lib = dylib_open(SUIL_GTK2_LIB_NAME, DYLIB_LAZY|DYLIB_GLOBAL);
if (!host->gtk_lib) {
SUIL_ERRORF("Failed to open %s (%s)\n",
- SUIL_GTK2_LIB_NAME, dlerror());
+ SUIL_GTK2_LIB_NAME, dylib_error());
return NULL;
}
gtk_init(NULL, NULL);
diff --git a/src/host.c b/src/host.c
index 6167377..90efceb 100644
--- a/src/host.c
+++ b/src/host.c
@@ -15,12 +15,12 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "dylib.h"
#include "suil_config.h"
#include "suil_internal.h"
#include "suil/suil.h"
-#include <dlfcn.h>
#include <stdlib.h>
int suil_argc = 0;
@@ -57,7 +57,7 @@ suil_host_free(SuilHost* host)
{
if (host) {
if (host->gtk_lib) {
- dlclose(host->gtk_lib);
+ dylib_close(host->gtk_lib);
}
free(host);
}
@@ -79,7 +79,7 @@ suil_load_init_module(const char* module_name)
SUIL_ERRORF("Corrupt init module %s\n", module_name);
}
- dlclose(lib);
+ dylib_close(lib);
}
#endif
diff --git a/src/instance.c b/src/instance.c
index 9235f6e..3cf5e06 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -14,6 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "dylib.h"
#include "suil_config.h"
#include "suil_internal.h"
@@ -21,7 +22,6 @@
#include "lv2/ui/ui.h"
#include "suil/suil.h"
-#include <dlfcn.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -188,7 +188,7 @@ open_wrapper(SuilHost* host,
wrapper->lib = lib;
} else {
SUIL_ERRORF("Corrupt wrap module %s\n", module_name);
- dlclose(lib);
+ dylib_close(lib);
}
return wrapper;
@@ -207,11 +207,11 @@ suil_instance_new(SuilHost* host,
const LV2_Feature* const* features)
{
// Open UI library
- dlerror();
- void* lib = dlopen(ui_binary_path, RTLD_NOW);
+ dylib_error();
+ void* lib = dylib_open(ui_binary_path, DYLIB_NOW);
if (!lib) {
SUIL_ERRORF("Unable to open UI library %s (%s)\n",
- ui_binary_path, dlerror());
+ ui_binary_path, dylib_error());
return NULL;
}
@@ -221,7 +221,7 @@ suil_instance_new(SuilHost* host,
if (!df) {
SUIL_ERRORF("Broken LV2 UI %s (no lv2ui_descriptor symbol found)\n",
ui_binary_path);
- dlclose(lib);
+ dylib_close(lib);
return NULL;
}
@@ -241,7 +241,7 @@ suil_instance_new(SuilHost* host,
if (!descriptor) {
SUIL_ERRORF("Failed to find descriptor for <%s> in %s\n",
ui_uri, ui_binary_path);
- dlclose(lib);
+ dylib_close(lib);
return NULL;
}
@@ -249,7 +249,7 @@ suil_instance_new(SuilHost* host,
SuilInstance* instance = (SuilInstance*)calloc(1, sizeof(SuilInstance));
if (!instance) {
SUIL_ERRORF("Failed to allocate memory for <%s> instance\n", ui_uri);
- dlclose(lib);
+ dylib_close(lib);
return NULL;
}
@@ -352,13 +352,13 @@ suil_instance_free(SuilInstance* instance)
instance->descriptor->cleanup(instance->handle);
}
- dlclose(instance->lib_handle);
+ dylib_close(instance->lib_handle);
// Close libraries and free everything
if (instance->wrapper) {
#ifndef _WIN32
// Never unload modules on windows, causes mysterious segfaults
- dlclose(instance->wrapper->lib);
+ dylib_close(instance->wrapper->lib);
#endif
free(instance->wrapper);
}
diff --git a/src/suil_internal.h b/src/suil_internal.h
index a217d60..c55e2ee 100644
--- a/src/suil_internal.h
+++ b/src/suil_internal.h
@@ -17,22 +17,12 @@
#ifndef SUIL_INTERNAL_H
#define SUIL_INTERNAL_H
+#include "dylib.h"
#include "suil_config.h"
#include "lv2/ui/ui.h"
#include "suil/suil.h"
-#ifdef _WIN32
-#include <windows.h>
-#define dlopen(path, flags) LoadLibrary(path)
-#define dlclose(lib) FreeLibrary((HMODULE)lib)
-#define inline __inline
-#define snprintf _snprintf
-static inline const char* dlerror(void) { return "Unknown error"; }
-#else
-#include <dlfcn.h>
-#endif
-
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -126,10 +116,10 @@ suil_open_module(const char* module_name)
mod_dir, SUIL_DIR_SEP,
SUIL_MODULE_PREFIX, module_name, SUIL_MODULE_EXT);
- dlerror();
- void* lib = dlopen(path, RTLD_NOW);
+ dylib_error();
+ void* lib = dylib_open(path, DYLIB_NOW);
if (!lib) {
- SUIL_ERRORF("Failed to open module %s (%s)\n", path, dlerror());
+ SUIL_ERRORF("Failed to open module %s (%s)\n", path, dylib_error());
}
free(path);