forked from microsoft/cppwinrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase_agile_ref.h
More file actions
129 lines (101 loc) · 3.04 KB
/
base_agile_ref.h
File metadata and controls
129 lines (101 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
WINRT_EXPORT namespace winrt
{
#if defined (WINRT_NO_MODULE_LOCK)
// Defining WINRT_NO_MODULE_LOCK is appropriate for apps (executables) or pinned DLLs (that don't support unloading)
// and can thus avoid the synchronization overhead imposed by the default module lock.
constexpr auto get_module_lock() noexcept
{
struct lock
{
constexpr uint32_t operator++() noexcept
{
return 1;
}
constexpr uint32_t operator--() noexcept
{
return 0;
}
constexpr explicit operator bool() noexcept
{
return true;
}
};
return lock{};
}
#elif defined (WINRT_CUSTOM_MODULE_LOCK)
// When WINRT_CUSTOM_MODULE_LOCK is defined, you must provide an implementation of winrt::get_module_lock()
// that returns an object that implements operator++ and operator--.
#else
// This is the default implementation for use with DllCanUnloadNow.
inline impl::atomic_ref_count& get_module_lock() noexcept
{
static impl::atomic_ref_count s_lock;
return s_lock;
}
#endif
}
namespace winrt::impl
{
template<bool UseModuleLock>
struct module_lock_updater;
template<>
struct module_lock_updater<true>
{
module_lock_updater() noexcept
{
++get_module_lock();
}
~module_lock_updater() noexcept
{
--get_module_lock();
}
};
template<>
struct module_lock_updater<false> {};
using update_module_lock = module_lock_updater<true>;
inline void* load_library(wchar_t const* library) noexcept
{
return WINRT_IMPL_LoadLibraryExW(library, nullptr, 0x00001000 /* LOAD_LIBRARY_SEARCH_DEFAULT_DIRS */);
}
inline hresult get_agile_reference(winrt::guid const& iid, void* object, void** reference) noexcept
{
return WINRT_IMPL_RoGetAgileReference(0, iid, object, reference);
}
}
WINRT_EXPORT namespace winrt
{
template <typename T>
struct agile_ref
{
agile_ref(std::nullptr_t = nullptr) noexcept {}
agile_ref(impl::com_ref<T> const& object)
{
if (object)
{
check_hresult(impl::get_agile_reference(guid_of<T>(), winrt::get_abi(object), m_ref.put_void()));
}
}
[[nodiscard]] impl::com_ref<T> get() const noexcept
{
if (!m_ref)
{
return nullptr;
}
void* result{};
m_ref->Resolve(guid_of<T>(), &result);
return { result, take_ownership_from_abi };
}
explicit operator bool() const noexcept
{
return static_cast<bool>(m_ref);
}
private:
com_ptr<impl::IAgileReference> m_ref;
};
template<typename T> agile_ref(T const&)->agile_ref<impl::wrapped_type_t<T>>;
template <typename T>
agile_ref<impl::wrapped_type_t<T>> make_agile(T const& object)
{
return object;
}
}