summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_win32.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_win32.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_win32.cpp')
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index f778977614a..e65509cc436 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -17,6 +17,8 @@
#include <unistd.h>
#endif
+#include <memory>
+
// MAME headers
#include "osdlib.h"
#include "osdcomm.h"
@@ -314,3 +316,85 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// osd_dynamic_bind
+//============================================================
+
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+// for classic desktop applications
+#define load_library(filename) LoadLibrary(filename)
+#else
+// for Windows Store universal applications
+#define load_library(filename) LoadPackagedLibrary(filename, 0)
+#endif
+
+namespace osd {
+
+class dynamic_module_win32_impl : public dynamic_module
+{
+public:
+ dynamic_module_win32_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_win32_impl() override
+ {
+ if (m_module != nullptr)
+ FreeLibrary(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>(GetProcAddress(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ TCHAR *tempstr = tstring_from_utf8(library.c_str());
+ if (!tempstr)
+ return nullptr;
+
+ HMODULE module = load_library(tempstr);
+
+ osd_free(tempstr);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ FreeLibrary(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ HMODULE m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_win32_impl>(names);
+}
+
+} // namespace osd