YSTest: COM.h 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
E/include/YCLib/COM.h
浏览该文件的文档.
1 /*
2 Copyright by FrankHB 2013.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
29 #ifndef YCL_MinGW32_INC_COMPtr_h_
30 #define YCL_MinGW32_INC_COMPtr_h_ 1
31
32 #include "MinGW32.h"
33 #include <objbase.h>
34
35 namespace platform_ex
36 {
37
39
40 class YF_API COM
42 {
43 protected:
45 ::HRESULT hResult;
46
47 public:
48 COM()
49 : hResult(::CoInitialize(nullptr))
50 {}
51 ~COM()
52 {
53 if(hResult == S_OK)
54 ::CoUninitialize();
55 }
56
58 DefGetter(ynothrow, ::HRESULT, HResult, hResult)
59 };
60
61
63 class YF_API COMException : public std::runtime_error
64 {
65 protected:
66 ::HRESULT hResult;
67
68 public:
69 COMException(::HRESULT h)
70 : runtime_error("COMException"), hResult(h)
71 {
72 yconstraint(FAILED(h) || h == S_FALSE);
73 }
74
75 DefGetter(ynothrow, ::HRESULT, HResult, hResult)
76 };
77
78
83 inline ::HRESULT
84 CheckHResult(::HRESULT h) ythrow(COMException)
85 {
86 if(FAILED(h))
87 throw COMException(h);
88 return h;
89 }
90
94 inline void
95 EnsureNonNull(void* p) ythrow(COMException)
96 {
97 if(!p)
98 throw COMException(S_FALSE);
99 }
100
101
102 /*
103 \brief COM 指针。
104 \warning 非虚析构。
105 */
106 template<class _iCOM>
107 class COMPtr
108 {
109 template<class _iOther>
110 friend class COMPtr;
111
112 public:
113 using InterfaceType = _iCOM;
114
115 protected:
116 InterfaceType* pInterface;
117
118 public:
119 COMPtr() ynothrow
120 : pInterface()
121 {}
122 COMPtr(std::nullptr_t) ynothrow
123 : pInterface()
124 {}
125 template<class _iOther>
126 COMPtr(_iOther* ptr) ynothrow
127 : pInterface(ptr)
128 {}
130 template<class _iOther>
131 COMPtr(_iOther& intf, ystdex::enable_if_t<!std::is_convertible<_iOther&,
132 COMPtr&>::value, int> = 0) ynothrow
133 : pInterface(&intf)
134 {
135 pInterface->AddRef();
136 }
137 COMPtr(const COMPtr& ptr) ynothrow
138 : pInterface(ptr.pInterface)
139 {
140 InternalAddRef();
141 }
143 template<class _iOther>
144 COMPtr(const COMPtr<_iOther>& ptr, ystdex::enable_if_t<
145 std::is_convertible<_iOther*, _iCOM*>::value, int> = 0) ynothrow
146 : pInterface(ptr.pInterface)
147 {
148 InternalAddRef();
149 }
150 COMPtr(COMPtr&& ptr) ynothrow
151 : pInterface()
152 {
153 ptr.swap(*this);
154 }
156 template<class _iOther>
157 COMPtr(COMPtr<_iOther>&& ptr, ystdex::enable_if_t<
158 std::is_convertible<_iOther*, _iCOM*>::value, int> = 0) ynothrow
159 : pInterface(ptr.pInterface)
160 {
161 ptr.pInterface = nullptr;
162 }
163 ~COMPtr() ynothrow
164 {
165 InternalRelease();
166 }
167
168 COMPtr&
169 operator=(std::nullptr_t) ynothrow
170 {
171 InternalRelease();
172 return *this;
173 }
174 COMPtr&
175 operator=(_iCOM* p) ynothrow
176 {
177 if(pInterface != p)
178 COMPtr(p).swap(*this);
179 return *this;
180 }
181 COMPtr&
182 operator=(const COMPtr& ptr) ynothrow
183 {
184 COMPtr(ptr).swap(*this);
185 return *this;
186 }
187 COMPtr&
188 operator=(COMPtr&& ptr) ynothrow
189 {
190 ptr.swap(*this);
191 return *this;
192 }
193
194 _iCOM&
195 operator*() const ynothrow
196 {
197 yconstraint(pInterface);
198
199 return *pInterface;
200 }
201
202 _iCOM*
203 operator->() const ynothrow
204 {
205 return pInterface;
206 }
207
208 explicit
209 operator bool() const ynothrow
210 {
211 return Get() != nullptr;
212 }
213
214 DefGetter(const ynothrow, _iCOM*, , pInterface)
215 DefGetter(const, _iCOM&, Object, EnsureNonNull(pInterface), *pInterface)
216 DefGetter(ynothrow, _iCOM*&, Ref, pInterface)
217
218 COMPtr<IUnknown>
219 As(REFIID riid) const ythrow(COMException)
220 {
221 yconstraint(pInterface);
222
223 COMPtr<IUnknown> res;
224
225 CheckHResult(pInterface->QueryInterface(riid,
226 reinterpret_cast<void**>(&res.ReleaseAndGetRef())));
227 return std::move(res);
228 }
229 template<class _iOther>
230 COMPtr<_iOther>
231 As() const ythrow(COMException)
232 {
233 yconstraint(pInterface);
234
235 COMPtr<_iOther> res;
236
237 CheckHResult(pInterface->QueryInterface(__uuidof(_iOther),
238 reinterpret_cast<void**>(&res.ReleaseAndGetRef())));
239 return std::move(res);
240 }
241
242 ::HRESULT
243 Cast(REFIID riid, COMPtr<IUnknown>& ptr) const ynothrow
244 {
245 yconstraint(pInterface);
246
247 return pInterface->QueryInterface(riid,
248 reinterpret_cast<void**>(&ptr.ReleaseAndGetRef()));
249 }
250 template<class _iOther>
251 ::HRESULT
252 Cast(COMPtr<_iOther>& ptr) const ynothrow
253 {
254 yconstraint(pInterface);
255
256 return pInterface->QueryInterface(__uuidof(_iOther),
257 reinterpret_cast<void**>(&ptr.ReleaseAndGetRef()));
258 }
259
260 InterfaceType*
261 Copy() const ynothrow
262 {
263 InternalAddRef();
264 return pInterface;
265 }
266 void*
267 Copy(REFIID riid) const ythrow(COMException)
268 {
269 yconstraint(pInterface);
270
271 void* p;
272
273 CheckHResult(pInterface->QueryInterface(riid, &p));
274 return p;
275 }
276
277 ::HRESULT
278 CopyTo(REFIID riid, void** ptr) const ynothrow
279 {
280 yconstraint(pInterface);
281
282 return pInterface->QueryInterface(riid, ptr);
283 }
284 template<typename _type>
285 ::HRESULT
286 CopyTo(_type*& p) const ynothrow
287 {
288 return pInterface->QueryInterface(__uuidof(_type),
289 reinterpret_cast<void**>(&p));
290 }
291
292 protected:
293 void
294 InternalAddRef() const ynothrow
295 {
296 if(pInterface)
297 pInterface->AddRef();
298 }
299
300 void
301 InternalRelease() ynothrow
302 {
303 if(const auto tmp = pInterface)
304 {
305 pInterface = nullptr;
306 tmp->Release();
307 }
308 }
309
310 public:
311 _iCOM*&
312 ReleaseAndGetRef() ynothrow
313 {
314 InternalRelease();
315 return pInterface;
316 }
317
318 void
319 swap(COMPtr& ptr) ynothrow
320 {
321 std::swap(pInterface, ptr.pInterface);
322 }
323 };
324
326
327 template<class _iCOM1, class _iCOM2>
328 inline bool
329 operator==(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
330 {
331 static_assert(std::is_base_of<_iCOM1, _iCOM2>::value
332 || std::is_base_of<_iCOM1, _iCOM2>::value,
333 "'_iCOM1' and '_iCOM2' pointers must be comparable");
334
335 return x.Get() == y.Get();
336 }
337 template<class _iCOM>
338 inline bool
339 operator==(const COMPtr<_iCOM>& x, std::nullptr_t) ynothrow
340 {
341 return !x.Get();
342 }
343 template<class _iCOM>
344 inline bool
345 operator==(std::nullptr_t, const COMPtr<_iCOM>& x) ynothrow
346 {
347 return !x.Get();
348 }
349
350 template<class _iCOM1, class _iCOM2>
351 inline bool
352 operator!=(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
353 {
354 return !(x == y);
355 }
356 template<class _iCOM>
357 inline bool
358 operator!=(const COMPtr<_iCOM>& x, std::nullptr_t) ynothrow
359 {
360 return x.Get();
361 }
362
363 template<class _iCOM>
364 inline bool
365 operator!=(std::nullptr_t, const COMPtr<_iCOM>& x) ynothrow
366 {
367 return x.Get();
368 }
369
370 template<class _iCOM1, class _iCOM2>
371 inline bool
372 operator<(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
373 {
374 static_assert(std::is_base_of<_iCOM1, _iCOM2>::value
375 || std::is_base_of<_iCOM1, _iCOM2>::value,
376 "'_iCOM1' and '_iCOM2' pointers must be comparable");
377
378 return x.Get() < y.Get();
379 }
380
381 template<class _iCOM>
382 void
383 Attach(COMPtr<_iCOM>& ptr, typename COMPtr<_iCOM>::InterfaceType* p) ynothrow
384 {
385 if(const auto p_interface = ptr.Get())
386 {
387 const auto ref(p_interface->Release());
388
389 yunused(ref);
390
391 yassume(ref != 0 || p_interface != p);
392 }
393 ptr.GetRef() = ptr;
394 }
395
396 template<class _iCOM>
397 _iCOM*
398 Detach(COMPtr<_iCOM>& ptr) ynothrow
399 {
400 auto p(ptr.Get());
401
402 ptr.GetRef() = nullptr;
403 return p;
404 }
405
406 template<class _iCOM>
407 unsigned long
408 Reset(COMPtr<_iCOM>& ptr) ynothrow
409 {
410 auto n(0UL);
411
412 if(const auto tmp = ptr.Get())
413 {
414 ptr.GetRef() = nullptr;
415 n = tmp->Release();
416 }
417 return n;
418 }
419
420 template<class _iCOM>
421 inline DefSwap(ynothrow, COMPtr<_iCOM>)
423
424
425 } // namespace platform_ex;
426
427 #endif
428
platform_ex::COMPtr::InternalRelease
void InternalRelease() ynothrow
Definition: include/YCLib/COM.h:300
platform_ex::COMPtr::InterfaceType
_iCOM InterfaceType
Definition: include/YCLib/COM.h:114
MinGW32.h
platform_ex::COMPtr::~COMPtr
~COMPtr() ynothrow
Definition: E/include/YCLib/COM.h:163
yunused
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:697
platform_ex::COMPtr::As
COMPtr< _iOther > As() const ythrow(COMException)
Definition: include/YCLib/COM.h:233
platform_ex::Detach
_iCOM * Detach(COMPtr< _iCOM > &ptr) ynothrow
Definition: include/YCLib/COM.h:396
platform_ex::COMPtr::Object
_iCOM Object
Definition: include/YCLib/COM.h:217
platform_ex::COMPtr::COMPtr
COMPtr(std::nullptr_t) ynothrow
Definition: E/include/YCLib/COM.h:122
platform_ex::COMPtr::operator=
COMPtr & operator=(std::nullptr_t) ynothrow
Definition: E/include/YCLib/COM.h:169
platform_ex::COMPtr::COMPtr
COMPtr(const COMPtr< _iOther > &ptr, ystdex::enable_if_t< std::is_convertible< _iOther *, _iCOM * >::value, int >=0) ynothrow
Definition: E/include/YCLib/COM.h:144
YF_API
#define YF_API
Definition: Platform.h:64
platform_ex::COMPtr::ReleaseAndGetRef
_iCOM *& ReleaseAndGetRef() ynothrow
Definition: E/include/YCLib/COM.h:312
ystdex::nullptr
const class ystdex::nullptr_t nullptr
platform_ex::COMPtr::CopyTo
::HRESULT CopyTo(REFIID riid, void **ptr) const ynothrow
Definition: E/include/YCLib/COM.h:278
platform_ex::EnsureNonNull
void EnsureNonNull(void *p) ythrow(COMException)
检查指针值，若为空则抛出 COMException 。
Definition: include/YCLib/COM.h:96
DefGetter
#define DefGetter(_q, _t, _n,...)
Definition: YBaseMacro.h:180
platform_ex::COMPtr::COMPtr
COMPtr() ynothrow
Definition: include/YCLib/COM.h:120
platform_ex::COMPtr::COMPtr
COMPtr() ynothrow
Definition: E/include/YCLib/COM.h:119
ystdex::swap
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
platform_ex::COMPtr::operator=
COMPtr & operator=(_iCOM *p) ynothrow
Definition: E/include/YCLib/COM.h:175
yassume
#define yassume
假定：环境语义。
Definition: cassert.h:58
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
platform_ex::COMPtr::COMPtr
COMPtr(_iOther *ptr) ynothrow
Definition: E/include/YCLib/COM.h:126
ythrow
#define ythrow(...)
YSLib 动态异常规范：根据是否使用异常规范宏指定或忽略动态异常规范。
Definition: ydef.h:476
yconstraint
#define yconstraint
约束：接口语义。
Definition: cassert.h:47
platform_ex::COMPtr::EnsureNonNull
_iCOM EnsureNonNull(pInterface)
platform_ex::operator!=
bool operator!=(const COMPtr< _iCOM1 > &x, const COMPtr< _iCOM2 > &y) ynothrow
Definition: include/YCLib/COM.h:351
platform_ex::COMException::COMException
COMException(::HRESULT h)
Definition: E/include/YCLib/COM.h:69
platform_ex::Attach
void Attach(COMPtr< _iCOM > &ptr, typename COMPtr< _iCOM >::InterfaceType *p) ynothrow
Definition: include/YCLib/COM.h:382
platform_ex::Reset
unsigned long Reset(COMPtr< _iCOM > &ptr) ynothrow
Definition: include/YCLib/COM.h:406
platform_ex::COMPtr::operator->
_iCOM * operator->() const ynothrow
Definition: E/include/YCLib/COM.h:203
platform_ex::COMPtr::Cast
::HRESULT Cast(REFIID riid, COMPtr< IUnknown > &ptr) const ynothrow
Definition: E/include/YCLib/COM.h:243
platform_ex::COMPtr::operator*
_iCOM & operator*() const ynothrow
Definition: E/include/YCLib/COM.h:195
platform_ex::COMPtr::CopyTo
::HRESULT CopyTo(_type *&p) const ynothrow
Definition: E/include/YCLib/COM.h:286
platform_ex::COMPtr::InternalAddRef
void InternalAddRef() const ynothrow
Definition: include/YCLib/COM.h:293
platform_ex::COM::COM
COM()
Definition: E/include/YCLib/COM.h:48
platform_ex::COMPtr::COMPtr
COMPtr(COMPtr &&ptr) ynothrow
Definition: E/include/YCLib/COM.h:150
platform_ex::operator==
bool operator==(const COMPtr< _iCOM1 > &x, const COMPtr< _iCOM2 > &y) ynothrow
Definition: include/YCLib/COM.h:328
platform_ex::COMException
COM 异常基类。
Definition: include/YCLib/COM.h:64
platform_ex::COMPtr::Copy
InterfaceType * Copy() const ynothrow
Definition: E/include/YCLib/COM.h:261
platform_ex::COMPtr::operator=
COMPtr & operator=(const COMPtr &ptr) ynothrow
Definition: E/include/YCLib/COM.h:182
platform_ex::COMPtr::Cast
::HRESULT Cast(COMPtr< _iOther > &ptr) const ynothrow
Definition: E/include/YCLib/COM.h:252
platform_ex::COMPtr::DefGetter
DefGetter(const ynothrow, _iCOM *,, pInterface) DefGetter(const
platform_ex::COMPtr
Definition: include/YCLib/COM.h:108
platform_ex::COMPtr::COMPtr
COMPtr(_iOther &intf, ystdex::enable_if_t<!std::is_convertible< _iOther &, COMPtr & >::value, int >=0) ynothrow
Definition: E/include/YCLib/COM.h:131
platform_ex::COMPtr::Copy
void * Copy(REFIID riid) const ythrow(COMException)
Definition: E/include/YCLib/COM.h:267
platform_ex::COMPtr::pInterface
InterfaceType * pInterface
Definition: include/YCLib/COM.h:117
platform_ex::COMPtr::operator=
COMPtr & operator=(COMPtr &&ptr) ynothrow
Definition: E/include/YCLib/COM.h:188
platform_ex::COMPtr::COMPtr
COMPtr(const COMPtr &ptr) ynothrow
Definition: E/include/YCLib/COM.h:137
platform_ex::COMPtr::COMPtr
COMPtr(COMPtr< _iOther > &&ptr, ystdex::enable_if_t< std::is_convertible< _iOther *, _iCOM * >::value, int >=0) ynothrow
Definition: E/include/YCLib/COM.h:157
ystdex::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_op.hpp:274
platform_ex::CheckHResult
inline::HRESULT CheckHResult(::HRESULT h) ythrow(COMException)
检查 ::HRESULT 值，若表示失败则抛出 COMException 。
Definition: include/YCLib/COM.h:85
platform_ex::COM::~COM
~COM()
Definition: E/include/YCLib/COM.h:51
platform_ex::COMPtr::swap
void swap(COMPtr &ptr) ynothrow
Definition: E/include/YCLib/COM.h:319