From 58dc78b6eba373d88fe7ef68f9ce3c2c43e635d6 Mon Sep 17 00:00:00 2001 From: Giuseppe Gorgoglione Date: Sat, 28 May 2016 04:14:15 +0200 Subject: Introduce dynamic_module This is a central cross-platform facility to dynamically bind functions from shared libraries. Updated all OSD modules to use it. --- src/osd/modules/lib/osdlib_unix.cpp | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'src/osd/modules/lib/osdlib_unix.cpp') 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 #include #include +#include + +#include +#include +#include + // MAME headers #include "osdcore.h" #include "osdlib.h" #include + //============================================================ // 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 &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(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(dlsym(module, symbol)); + + if (function != nullptr) + { + m_module = module; + return function; + } + else + { + dlclose(module); + } + } + } + + return nullptr; + } + +private: + std::vector m_libraries; + void * m_module; +}; + +dynamic_module::ptr dynamic_module::open(std::vector &&names) +{ + return std::make_unique(names); +} + +} // namespace osd -- cgit v1.2.3