1 // This file is part of Desktop App Toolkit,
2 // a set of libraries for developing nice desktop applications.
3 //
4 // For license and copyright information please follow this link:
5 // https://github.com/desktop-app/legal/blob/master/LEGAL
6 //
7 #pragma once
8 
9 #include <crl/common/crl_common_config.h>
10 
11 #ifdef CRL_USE_WINAPI
12 
13 #include <exception>
14 #include <crl/winapi/crl_winapi_windows_h.h>
15 
16 namespace crl::details {
17 
18 class dll {
19 public:
20 	enum class own_policy {
21 		owner,
22 		load_and_leak,
23 		use_existing,
24 	};
dll(LPCWSTR library,own_policy policy)25 	dll(LPCWSTR library, own_policy policy)
26 	: _handle((policy == own_policy::use_existing)
27 		? GetModuleHandle(library)
28 		: LoadLibrary(library))
29 	, _policy(policy) {
30 	}
31 
32 	template <typename Function>
try_load(Function & function,const char * name)33 	bool try_load(Function &function, const char *name) const {
34 		if (!_handle) {
35 			return false;
36 		}
37 		function = reinterpret_cast<Function>(GetProcAddress(_handle, name));
38 		return (function != nullptr);
39 	}
40 
41 	template <typename Function>
load(Function & function,const char * name)42 	void load(Function &function, const char *name) const {
43 		if (!try_load(function, name)) {
44 			Failed();
45 		}
46 	}
47 
~dll()48 	~dll() {
49 		if (_handle && _policy == own_policy::owner) {
50 			FreeLibrary(_handle);
51 		}
52 	}
53 
54 private:
Failed()55 	[[noreturn]] static void Failed() {
56 		std::terminate();
57 	}
58 
59 	HMODULE _handle = nullptr;
60 	own_policy _policy = own_policy::use_existing;
61 
62 };
63 
64 } // namespace crl::details
65 
66 #endif // CRL_USE_WINAPI
67