YSTest: COM.h 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
include/YCLib/COM.h
浏览该文件的文档.
1 /*
2 © 2013-2014 FrankHB.
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 "YCLib/YModules.h"
33 #include YFM_MinGW32_YCLib_MinGW32
34 #include <objbase.h>
35
36 namespace platform_ex
37 {
38
40
41 class YF_API COM
43 {
44 protected:
46 ::HRESULT hResult;
47
48 public:
49 COM()
50 : hResult(::CoInitialize(nullptr))
51 {}
52 ~COM()
53 {
54 if(hResult == S_OK)
55 ::CoUninitialize();
56 }
57
59 DefGetter(ynothrow, ::HRESULT, HResult, hResult)
60 };
61
62
64 class YF_API COMException : public std::runtime_error
65 {
66 protected:
67 ::HRESULT hResult;
68
69 public:
70 COMException(::HRESULT h)
71 : runtime_error("COMException"), hResult(h)
72 {
73 yconstraint(FAILED(h) || h == S_FALSE);
74 }
75
76 DefGetter(ynothrow, ::HRESULT, HResult, hResult)
77 };
78
79
84 inline ::HRESULT
85 CheckHResult(::HRESULT h) ythrow(COMException)
86 {
87 if(FAILED(h))
88 throw COMException(h);
89 return h;
90 }
91
95 inline void
96 EnsureNonNull(void* p) ythrow(COMException)
97 {
98 if(!p)
99 throw COMException(S_FALSE);
100 }
101
102
103 /*
104 \brief COM 指针。
105 \warning 非虚析构。
106 */
107 template<class _iCOM>
108 class COMPtr
109 {
110 template<class _iOther>
111 friend class COMPtr;
112
113 public:
114 using InterfaceType = _iCOM;
115
116 protected:
117 InterfaceType* pInterface;
118
119 public:
120 COMPtr() ynothrow
121 : pInterface()
122 {}
123 COMPtr(std::nullptr_t) ynothrow
124 : pInterface()
125 {}
126 template<class _iOther>
127 COMPtr(_iOther* ptr) ynothrow
128 : pInterface(ptr)
129 {}
131 template<class _iOther>
132 COMPtr(_iOther& intf, ystdex::enable_if_t<!std::is_convertible<_iOther&,
133 COMPtr&>::value, int> = 0) ynothrow
134 : pInterface(&intf)
135 {
136 pInterface->AddRef();
137 }
138 COMPtr(const COMPtr& ptr) ynothrow
139 : pInterface(ptr.pInterface)
140 {
141 InternalAddRef();
142 }
144 template<class _iOther>
145 COMPtr(const COMPtr<_iOther>& ptr, ystdex::enable_if_t<
146 std::is_convertible<_iOther*, _iCOM*>::value, int> = 0) ynothrow
147 : pInterface(ptr.pInterface)
148 {
149 InternalAddRef();
150 }
151 COMPtr(COMPtr&& ptr) ynothrow
152 : pInterface()
153 {
154 ptr.swap(*this);
155 }
157 template<class _iOther>
158 COMPtr(COMPtr<_iOther>&& ptr, ystdex::enable_if_t<
159 std::is_convertible<_iOther*, _iCOM*>::value, int> = 0) ynothrow
160 : pInterface(ptr.pInterface)
161 {
162 ptr.pInterface = nullptr;
163 }
165 ~COMPtr()
166 {
167 InternalRelease();
168 }
169
170 COMPtr&
171 operator=(std::nullptr_t) ynothrow
172 {
173 InternalRelease();
174 return *this;
175 }
176 COMPtr&
177 operator=(_iCOM* p) ynothrow
178 {
179 if(pInterface != p)
180 COMPtr(p).swap(*this);
181 return *this;
182 }
183 COMPtr&
184 operator=(const COMPtr& ptr) ynothrow
185 {
186 COMPtr(ptr).swap(*this);
187 return *this;
188 }
189 COMPtr&
190 operator=(COMPtr&& ptr) ynothrow
191 {
192 ptr.swap(*this);
193 return *this;
194 }
195
197 _iCOM&
198 operator*() const ynothrowv
199 {
200 yconstraint(pInterface);
201 return *pInterface;
202 }
203
204 _iCOM*
205 operator->() const ynothrow
206 {
207 return pInterface;
208 }
209
210 explicit
211 operator bool() const ynothrow
212 {
213 return Get() != nullptr;
214 }
215
216 DefGetter(const ynothrow, _iCOM*, , pInterface)
217 DefGetter(const, _iCOM&, Object, EnsureNonNull(pInterface), *pInterface)
218 DefGetter(ynothrow, _iCOM*&, Ref, pInterface)
219
220 COMPtr<IUnknown>
221 As(REFIID riid) const ythrow(COMException)
222 {
223 yconstraint(pInterface);
224
225 COMPtr<IUnknown> res;
226
227 CheckHResult(pInterface->QueryInterface(riid,
228 reinterpret_cast<void**>(&res.ReleaseAndGetRef())));
229 return res;
230 }
231 template<class _iOther>
232 COMPtr<_iOther>
233 As() const ythrow(COMException)
234 {
235 yconstraint(pInterface);
236
237 COMPtr<_iOther> res;
238
239 CheckHResult(pInterface->QueryInterface(__uuidof(_iOther),
240 reinterpret_cast<void**>(&res.ReleaseAndGetRef())));
241 return res;
242 }
243
244 ::HRESULT
245 Cast(REFIID riid, COMPtr<IUnknown>& ptr) const ynothrow
246 {
247 yconstraint(pInterface);
248 return pInterface->QueryInterface(riid,
249 reinterpret_cast<void**>(&ptr.ReleaseAndGetRef()));
250 }
251 template<class _iOther>
252 ::HRESULT
253 Cast(COMPtr<_iOther>& ptr) const ynothrow
254 {
255 yconstraint(pInterface);
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 return pInterface->QueryInterface(riid, ptr);
282 }
283 template<typename _type>
284 ::HRESULT
285 CopyTo(_type*& p) const ynothrow
286 {
287 return pInterface->QueryInterface(__uuidof(_type),
288 reinterpret_cast<void**>(&p));
289 }
290
291 protected:
292 void
293 InternalAddRef() const ynothrow
294 {
295 if(pInterface)
296 pInterface->AddRef();
297 }
298
299 void
300 InternalRelease() ynothrow
301 {
302 if(const auto tmp = pInterface)
303 {
304 pInterface = nullptr;
305 tmp->Release();
306 }
307 }
308
309 public:
310 _iCOM*&
311 ReleaseAndGetRef() ynothrow
312 {
313 InternalRelease();
314 return pInterface;
315 }
316
317 void
318 swap(COMPtr& ptr) ynothrow
319 {
320 std::swap(pInterface, ptr.pInterface);
321 }
322 };
323
325
326 template<class _iCOM1, class _iCOM2>
327 inline bool
328 operator==(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
329 {
330 static_assert(std::is_base_of<_iCOM1, _iCOM2>::value
331 || std::is_base_of<_iCOM1, _iCOM2>::value,
332 "'_iCOM1' and '_iCOM2' pointers must be comparable");
333
334 return x.Get() == y.Get();
335 }
336 template<class _iCOM>
337 inline bool
338 operator==(const COMPtr<_iCOM>& x, std::nullptr_t) ynothrow
339 {
340 return !x.Get();
341 }
342 template<class _iCOM>
343 inline bool
344 operator==(std::nullptr_t, const COMPtr<_iCOM>& x) ynothrow
345 {
346 return !x.Get();
347 }
348
349 template<class _iCOM1, class _iCOM2>
350 inline bool
351 operator!=(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
352 {
353 return !(x == y);
354 }
355 template<class _iCOM>
356 inline bool
357 operator!=(const COMPtr<_iCOM>& x, std::nullptr_t) ynothrow
358 {
359 return x.Get();
360 }
361
362 template<class _iCOM>
363 inline bool
364 operator!=(std::nullptr_t, const COMPtr<_iCOM>& x) ynothrow
365 {
366 return x.Get();
367 }
368
369 template<class _iCOM1, class _iCOM2>
370 inline bool
371 operator<(const COMPtr<_iCOM1>& x, const COMPtr<_iCOM2>& y) ynothrow
372 {
373 static_assert(std::is_base_of<_iCOM1, _iCOM2>::value
374 || std::is_base_of<_iCOM1, _iCOM2>::value,
375 "'_iCOM1' and '_iCOM2' pointers must be comparable");
376
377 return x.Get() < y.Get();
378 }
379
380 template<class _iCOM>
381 void
382 Attach(COMPtr<_iCOM>& ptr, typename COMPtr<_iCOM>::InterfaceType* p) ynothrow
383 {
384 if(const auto p_interface = ptr.Get())
385 {
386 const auto ref(p_interface->Release());
387
388 yunused(ref);
389 yassume(ref != 0 || p_interface != p);
390 }
391 ptr.GetRef() = ptr;
392 }
393
394 template<class _iCOM>
395 _iCOM*
396 Detach(COMPtr<_iCOM>& ptr) ynothrow
397 {
398 auto p(ptr.Get());
399
400 ptr.GetRef() = nullptr;
401 return p;
402 }
403
404 template<class _iCOM>
405 unsigned long
406 Reset(COMPtr<_iCOM>& ptr) ynothrow
407 {
408 auto n(0UL);
409
410 if(const auto tmp = ptr.Get())
411 {
412 ptr.GetRef() = nullptr;
413 n = tmp->Release();
414 }
415 return n;
416 }
417
418 template<class _iCOM>
419 inline DefSwap(ynothrow, COMPtr<_iCOM>)
421
422
423 } // namespace platform_ex;
424
425 #endif
426
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
platform_ex::COM::hResult
::HRESULT hResult
Definition: include/YCLib/COM.h:46
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:494
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: include/YCLib/COM.h:123
platform_ex::COMPtr::operator=
COMPtr & operator=(std::nullptr_t) ynothrow
Definition: include/YCLib/COM.h:171
YModules.h
platform_ex::COMPtr::COMPtr
COMPtr(const COMPtr< _iOther > &ptr, ystdex::enable_if_t< std::is_convertible< _iOther *, _iCOM * >::value, int >=0) ynothrow
Definition: include/YCLib/COM.h:145
YF_API
#define YF_API
Definition: Platform.h:64
platform_ex::COMPtr::ReleaseAndGetRef
_iCOM *& ReleaseAndGetRef() ynothrow
Definition: include/YCLib/COM.h:311
ystdex::nullptr
const class ystdex::nullptr_t nullptr
platform_ex::COMPtr::CopyTo
::HRESULT CopyTo(REFIID riid, void **ptr) const ynothrow
Definition: 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
ystdex::swap
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
platform_ex::COMPtr::operator=
COMPtr & operator=(_iCOM *p) ynothrow
Definition: include/YCLib/COM.h:177
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: include/YCLib/COM.h:127
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::COMPtr::operator*
_iCOM & operator*() const ynothrowv
Definition: include/YCLib/COM.h:198
platform_ex::COMException::COMException
COMException(::HRESULT h)
Definition: include/YCLib/COM.h:70
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: include/YCLib/COM.h:205
platform_ex::COMPtr::Cast
::HRESULT Cast(REFIID riid, COMPtr< IUnknown > &ptr) const ynothrow
Definition: include/YCLib/COM.h:245
platform_ex::COMPtr::CopyTo
::HRESULT CopyTo(_type *&p) const ynothrow
Definition: include/YCLib/COM.h:285
platform_ex::COMException::hResult
::HRESULT hResult
Definition: include/YCLib/COM.h:67
platform_ex::COMPtr::InternalAddRef
void InternalAddRef() const ynothrow
Definition: include/YCLib/COM.h:293
platform_ex::COM::COM
COM()
Definition: include/YCLib/COM.h:49
platform_ex::COMPtr::COMPtr
COMPtr(COMPtr &&ptr) ynothrow
Definition: include/YCLib/COM.h:151
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: include/YCLib/COM.h:261
platform_ex::COMPtr::operator=
COMPtr & operator=(const COMPtr &ptr) ynothrow
Definition: include/YCLib/COM.h:184
platform_ex::COMPtr::Cast
::HRESULT Cast(COMPtr< _iOther > &ptr) const ynothrow
Definition: include/YCLib/COM.h:253
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: include/YCLib/COM.h:132
platform_ex::COMPtr::Copy
void * Copy(REFIID riid) const ythrow(COMException)
Definition: 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: include/YCLib/COM.h:190
platform_ex::COMPtr::COMPtr
COMPtr(const COMPtr &ptr) ynothrow
Definition: include/YCLib/COM.h:138
platform_ex::COMPtr::COMPtr
COMPtr(COMPtr< _iOther > &&ptr, ystdex::enable_if_t< std::is_convertible< _iOther *, _iCOM * >::value, int >=0) ynothrow
Definition: include/YCLib/COM.h:158
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::COMPtr::~COMPtr
~COMPtr()
Definition: include/YCLib/COM.h:165
platform_ex::COM::~COM
~COM()
Definition: include/YCLib/COM.h:52
platform_ex::COMPtr::swap
void swap(COMPtr &ptr) ynothrow
Definition: include/YCLib/COM.h:318