diff options
author | 2016-05-28 04:14:15 +0200 | |
---|---|---|
committer | 2016-06-11 20:14:09 +0200 | |
commit | 58dc78b6eba373d88fe7ef68f9ce3c2c43e635d6 (patch) | |
tree | 90af8c2c2323070c2c336153de8376d83a3f1f44 /src/osd/modules/lib/osdlib_win32.cpp | |
parent | ea1b66f146e4c6663e06b124f8665f878c43ce0c (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.cpp | 84 |
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 |