aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/WinTypes.h
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-11-22 09:47:07 +1100
committerNeil <nyamatongwe@gmail.com>2021-11-22 09:47:07 +1100
commit0ef4d6169062ed872c11c176af07b366b636c45e (patch)
treeb4e596c798c6e5f938fc9bfe5c4ae8a75ecb66a4 /win32/WinTypes.h
parent8904b645419b8deb202046bbc785440d0d006404 (diff)
downloadscintilla-mirror-0ef4d6169062ed872c11c176af07b366b636c45e.tar.gz
Move common Win32 functions for releasing IUnknown* and DLL function access into
new WinType.h header.
Diffstat (limited to 'win32/WinTypes.h')
-rw-r--r--win32/WinTypes.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/win32/WinTypes.h b/win32/WinTypes.h
new file mode 100644
index 000000000..44a12f38b
--- /dev/null
+++ b/win32/WinTypes.h
@@ -0,0 +1,59 @@
+// Scintilla source code edit control
+/** @file WinTypes.h
+ ** Implement safe release of COM objects and access to functions in DLLs.
+ ** Header contains all implementation - there is no .cxx file.
+ **/
+// Copyright 2020-2021 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef WINTYPES_H
+#define WINTYPES_H
+
+namespace Scintilla::Internal {
+
+// Release an IUnknown* and set to nullptr.
+// While IUnknown::Release must be noexcept, it isn't marked as such so produces
+// warnings which are avoided by the catch.
+template <class T>
+inline void ReleaseUnknown(T *&ppUnknown) noexcept {
+ if (ppUnknown) {
+ try {
+ ppUnknown->Release();
+ } catch (...) {
+ // Never occurs
+ }
+ ppUnknown = nullptr;
+ }
+}
+
+struct UnknownReleaser {
+ // Called by unique_ptr to destroy/free the resource
+ template <class T>
+ void operator()(T *pUnknown) noexcept {
+ // same as ReleaseUnknown() in PlatWin.h
+ try {
+ pUnknown->Release();
+ } catch (...) {
+ // IUnknown::Release must not throw, ignore if it does.
+ }
+ }
+};
+
+
+/// Find a function in a DLL and convert to a function pointer.
+/// This avoids undefined and conditionally defined behaviour.
+template<typename T>
+inline T DLLFunction(HMODULE hModule, LPCSTR lpProcName) noexcept {
+ if (!hModule) {
+ return nullptr;
+ }
+ FARPROC function = ::GetProcAddress(hModule, lpProcName);
+ static_assert(sizeof(T) == sizeof(function));
+ T fp {};
+ memcpy(&fp, &function, sizeof(T));
+ return fp;
+}
+
+}
+
+#endif