summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Brad Hughes <bradhugh@outlook.com>2016-11-18 14:06:11 -0500
committer Brad Hughes <bradhugh@outlook.com>2016-11-20 13:41:44 -0500
commit17c9b0b7847e71ac49b756e6a0cfc0841ce52ac0 (patch)
treeddceeec41f182007d71f496189c9ce7f020fae62
parente4c856dd1ff81ed945c7edd96993f3d909be9ded (diff)
Created DYNAMIC_API macros for cleaner definition of dynamically linked functions
-rw-r--r--src/osd/modules/lib/osdlib.h38
-rw-r--r--src/osd/modules/monitor/monitor_dxgi.cpp18
-rw-r--r--src/osd/modules/sound/xaudio2_sound.cpp22
3 files changed, 53 insertions, 25 deletions
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index 7580c92dedd..8fcff19dac8 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -98,4 +98,42 @@ protected:
} // namespace osd
+//=========================================================================================================================
+// Dynamic API helpers. Useful in creating a singleton object that can be called with DYNAMIC_CALL macro for an entire API
+// Usage for defining an API is below
+//
+// DYNAMIC_API_BEGIN(dxgi, { "dxgi.dll" })
+// DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
+// DYNAMIC_API_END()
+//
+// Calling then looks like: DYNAMIC_CALL(dxgi, CreateDXGIFactory1, p1, p2, etc)
+//=========================================================================================================================
+
+#if !defined(OSD_UWP)
+
+#define DYNAMIC_API_BEGIN(apiname, ...) namespace osd { namespace dynamicapi { \
+class apiname##_api { \
+private: \
+ osd::dynamic_module::ptr m_module = osd::dynamic_module::open( { __VA_ARGS__ } ); \
+public: \
+ static apiname##_api &instance() { static apiname##_api api; return api; }
+
+#define DYNAMIC_API_FN(ret, conv, apifunc, ...) ret(conv *m_##apifunc##_pfn)( __VA_ARGS__ ) = m_module->bind<ret(conv *)( __VA_ARGS__ )>(#apifunc);
+
+#define DYNAMIC_API_END() };}}
+
+#define DYNAMIC_CALL(apiname, fname, ...) (*osd::dynamicapi::##apiname##_api::instance().m_##fname##_pfn) ( __VA_ARGS__ )
+#define DYNAMIC_API_TEST(apiname, fname) (osd::dynamicapi::##apiname##_api::instance().m_##fname##_pfn != nullptr)
+
+#else
+
+#define DYNAMIC_API_BEGIN(apiname, ...)
+#define DYNAMIC_API_FN(ret, conv, apifunc, ...)
+#define DYNAMIC_API_END()
+
+#define DYNAMIC_CALL(apiname, fname, ...) fname( __VA_ARGS__ )
+#define DYNAMIC_API_TEST(apiname, fname) (true)
+
+#endif
+
#endif /* __OSDLIB__ */
diff --git a/src/osd/modules/monitor/monitor_dxgi.cpp b/src/osd/modules/monitor/monitor_dxgi.cpp
index 33360922764..c536a52efa6 100644
--- a/src/osd/modules/monitor/monitor_dxgi.cpp
+++ b/src/osd/modules/monitor/monitor_dxgi.cpp
@@ -25,6 +25,10 @@
#include "window.h"
#include "windows/video.h"
+DYNAMIC_API_BEGIN(dxgi, "dxgi.dll")
+ DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
+DYNAMIC_API_END()
+
using namespace Microsoft::WRL;
class dxgi_monitor_info : public osd_monitor_info
@@ -54,26 +58,18 @@ public:
}
};
-typedef DWORD(WINAPI *dxgi_create_factory_fn)(REFIID, void**);
class dxgi_monitor_module : public monitor_module_base
{
-private:
- osd::dynamic_module::ptr m_dxgi_module;
- dxgi_create_factory_fn m_create_factory_fn;
-
public:
dxgi_monitor_module()
- : monitor_module_base(OSD_MONITOR_PROVIDER, "dxgi"),
- m_dxgi_module(osd::dynamic_module::open({"dxgi.dll"})),
- m_create_factory_fn(nullptr)
+ : monitor_module_base(OSD_MONITOR_PROVIDER, "dxgi")
{
}
bool probe() override
{
- m_create_factory_fn = m_dxgi_module->bind<dxgi_create_factory_fn>("CreateDXGIFactory1");
- if (m_create_factory_fn == nullptr)
+ if(!DYNAMIC_API_TEST(dxgi, CreateDXGIFactory1))
return false;
return true;
@@ -133,7 +129,7 @@ protected:
ComPtr<IDXGIFactory2> factory;
ComPtr<IDXGIAdapter> adapter;
- result = m_create_factory_fn(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(factory.GetAddressOf()));
+ result = DYNAMIC_CALL(dxgi, CreateDXGIFactory1, __uuidof(IDXGIFactory2), reinterpret_cast<void**>(factory.GetAddressOf())); // m_create_factory_fn();
if (result != ERROR_SUCCESS)
{
osd_printf_error("CreateDXGIFactory1 failed with error 0x%x\n", static_cast<unsigned int>(result));
diff --git a/src/osd/modules/sound/xaudio2_sound.cpp b/src/osd/modules/sound/xaudio2_sound.cpp
index da5907cc462..0bb9f296b2c 100644
--- a/src/osd/modules/sound/xaudio2_sound.cpp
+++ b/src/osd/modules/sound/xaudio2_sound.cpp
@@ -123,8 +123,11 @@ public:
typedef std::unique_ptr<IXAudio2MasteringVoice, xaudio2_custom_deleter> mastering_voice_ptr;
typedef std::unique_ptr<IXAudio2SourceVoice, xaudio2_custom_deleter> src_voice_ptr;
-// Typedef for pointer to XAudio2Create
-typedef HRESULT (WINAPI *xaudio2_create_ptr)(IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR);
+// XAudio2 API
+//
+DYNAMIC_API_BEGIN(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll")
+ DYNAMIC_API_FN(HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR)
+DYNAMIC_API_END()
//============================================================
// Helper classes
@@ -205,8 +208,6 @@ private:
uint32_t m_overflows;
uint32_t m_underflows;
BOOL m_in_underflow;
- osd::dynamic_module::ptr m_xaudio_dll;
- xaudio2_create_ptr XAudio2Create;
BOOL m_initialized;
public:
@@ -228,7 +229,6 @@ public:
m_overflows(0),
m_underflows(0),
m_in_underflow(FALSE),
- XAudio2Create(nullptr),
m_initialized(FALSE)
{
}
@@ -268,13 +268,7 @@ private:
bool sound_xaudio2::probe()
{
- m_xaudio_dll = osd::dynamic_module::open({ "XAudio2_9.dll", "XAudio2_8.dll" });
- if (m_xaudio_dll == nullptr)
- return false;
-
- XAudio2Create = m_xaudio_dll->bind<xaudio2_create_ptr>("XAudio2Create");
-
- return (XAudio2Create ? true : false);
+ return DYNAMIC_API_TEST(xaudio2, XAudio2Create);
}
//============================================================
@@ -291,14 +285,14 @@ int sound_xaudio2::init(osd_options const &options)
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Make sure our XAudio2Create entrypoint is bound
- if (!XAudio2Create)
+ if (!DYNAMIC_API_TEST(xaudio2, XAudio2Create))
{
osd_printf_error("Could not find XAudio2. Please try to reinstall DirectX runtime package.\n");
return 1;
}
// Create the IXAudio2 object
- HR_GOERR(this->XAudio2Create(m_xAudio2.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR));
+ HR_GOERR(DYNAMIC_CALL(xaudio2, XAudio2Create, m_xAudio2.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR));
// make a format description for what we want
format.wBitsPerSample = 16;