summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_unix.cpp
diff options
context:
space:
mode:
author Giuseppe Gorgoglione <gorgogsp@gmail.com>2016-05-28 04:14:15 +0200
committer Giuseppe Gorgoglione <gorgogsp@gmail.com>2016-06-11 20:14:09 +0200
commit58dc78b6eba373d88fe7ef68f9ce3c2c43e635d6 (patch)
tree90af8c2c2323070c2c336153de8376d83a3f1f44 /src/osd/modules/lib/osdlib_unix.cpp
parentea1b66f146e4c6663e06b124f8665f878c43ce0c (diff)
Introduce dynamic_module
This is a central cross-platform facility to dynamically bind functions from shared libraries. Updated all OSD modules to use it.
Diffstat (limited to 'src/osd/modules/lib/osdlib_unix.cpp')
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 52999835a1c..81d9967ff64 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -13,12 +13,19 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
+#include <dlfcn.h>
+
+#include <codecvt>
+#include <iomanip>
+#include <memory>
+
// MAME headers
#include "osdcore.h"
#include "osdlib.h"
#include <SDL2/SDL.h>
+
//============================================================
// osd_getenv
//============================================================
@@ -159,3 +166,71 @@ char *osd_get_clipboard_text(void)
}
#endif
+
+//============================================================
+// dynamic_module_posix_impl
+//============================================================
+
+namespace osd {
+
+class dynamic_module_posix_impl : public dynamic_module
+{
+public:
+ dynamic_module_posix_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_posix_impl() override
+ {
+ if (m_module != nullptr)
+ dlclose(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ void *module = dlopen(library.c_str(), RTLD_LAZY);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ dlclose(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ void * m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_posix_impl>(names);
+}
+
+} // namespace osd