diff options
author | Neil <nyamatongwe@gmail.com> | 2021-11-22 09:47:07 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2021-11-22 09:47:07 +1100 |
commit | 0ef4d6169062ed872c11c176af07b366b636c45e (patch) | |
tree | b4e596c798c6e5f938fc9bfe5c4ae8a75ecb66a4 /win32/WinTypes.h | |
parent | 8904b645419b8deb202046bbc785440d0d006404 (diff) | |
download | scintilla-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.h | 59 |
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 |