aboutsummaryrefslogtreecommitdiff
path: root/CPP/Common/MyCom.h
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Common/MyCom.h')
-rw-r--r--CPP/Common/MyCom.h153
1 files changed, 150 insertions, 3 deletions
diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h
index 65c4330..a3cc3c8 100644
--- a/CPP/Common/MyCom.h
+++ b/CPP/Common/MyCom.h
@@ -17,6 +17,7 @@ public:
17 ~CMyComPtr() { if (_p) _p->Release(); } 17 ~CMyComPtr() { if (_p) _p->Release(); }
18 void Release() { if (_p) { _p->Release(); _p = NULL; } } 18 void Release() { if (_p) { _p->Release(); _p = NULL; } }
19 operator T*() const { return (T*)_p; } 19 operator T*() const { return (T*)_p; }
20 T* Interface() const { return (T*)_p; }
20 // T& operator*() const { return *_p; } 21 // T& operator*() const { return *_p; }
21 T** operator&() { return &_p; } 22 T** operator&() { return &_p; }
22 T* operator->() const { return _p; } 23 T* operator->() const { return _p; }
@@ -68,6 +69,112 @@ public:
68 } 69 }
69}; 70};
70 71
72
73template <class iface, class cls>
74class CMyComPtr2
75{
76 cls* _p;
77
78 CMyComPtr2(const CMyComPtr2<iface, cls>& lp);
79 CMyComPtr2(cls* p);
80 CMyComPtr2(iface* p);
81 iface* operator=(const CMyComPtr2<iface, cls>& lp);
82 iface* operator=(cls* p);
83 iface* operator=(iface* p);
84public:
85 CMyComPtr2(): _p(NULL) {}
86 ~CMyComPtr2()
87 {
88 if (_p)
89 {
90 iface *ip = _p;
91 ip->Release();
92 }
93 }
94 // void Release() { if (_p) { (iface *)_p->Release(); _p = NULL; } }
95 cls* operator->() const { return _p; }
96 cls* ClsPtr() const { return _p; }
97 operator iface*() const
98 {
99 iface *ip = _p;
100 return ip;
101 }
102 iface* Interface() const
103 {
104 iface *ip = _p;
105 return ip;
106 }
107 // operator bool() const { return _p != NULL; }
108 bool IsDefined() const { return _p != NULL; }
109 void Create_if_Empty()
110 {
111 if (!_p)
112 {
113 _p = new cls;
114 iface *ip = _p;
115 ip->AddRef();
116 }
117 }
118 iface* Detach()
119 {
120 iface *ip = _p;
121 _p = NULL;
122 return ip;
123 }
124 void SetFromCls(cls *src)
125 {
126 if (src)
127 {
128 iface *ip = src;
129 ip->AddRef();
130 }
131 if (_p)
132 {
133 iface *ip = _p;
134 ip->Release();
135 }
136 _p = src;
137 }
138};
139
140
141template <class iface, class cls>
142class CMyComPtr2_Create
143{
144 cls* _p;
145
146 CMyComPtr2_Create(const CMyComPtr2_Create<iface, cls>& lp);
147 CMyComPtr2_Create(cls* p);
148 CMyComPtr2_Create(iface* p);
149 iface* operator=(const CMyComPtr2_Create<iface, cls>& lp);
150 iface* operator=(cls* p);
151 iface* operator=(iface* p);
152public:
153 CMyComPtr2_Create(): _p(new cls)
154 {
155 iface *ip = _p;
156 ip->AddRef();
157 }
158 ~CMyComPtr2_Create()
159 {
160 iface *ip = _p;
161 ip->Release();
162 }
163 cls* operator->() const { return _p; }
164 cls* ClsPtr() const { return _p; }
165 operator iface*() const
166 {
167 iface *ip = _p;
168 return ip;
169 }
170 iface* Interface() const
171 {
172 iface *ip = _p;
173 return ip;
174 }
175};
176
177
71#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \ 178#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \
72 CMyComPtr<i> v; (unk)->QueryInterface(IID_ ## i, (void **)&v); 179 CMyComPtr<i> v; (unk)->QueryInterface(IID_ ## i, (void **)&v);
73 180
@@ -234,16 +341,56 @@ protected:
234 Z7_COM_QI_ENTRY_UNKNOWN(i) \ 341 Z7_COM_QI_ENTRY_UNKNOWN(i) \
235 Z7_COM_QI_ENTRY(i) 342 Z7_COM_QI_ENTRY(i)
236 343
237#define Z7_COM_QI_END \ 344
345#define Z7_COM_ADDREF_RELEASE_MT \
346 private: \
347 STDMETHOD_(ULONG, AddRef)() Z7_override Z7_final \
348 { return (ULONG)InterlockedIncrement((LONG *)&_m_RefCount); } \
349 STDMETHOD_(ULONG, Release)() Z7_override Z7_final \
350 { const LONG v = InterlockedDecrement((LONG *)&_m_RefCount); \
351 if (v != 0) return (ULONG)v; \
352 delete this; return 0; }
353
354#define Z7_COM_QI_END_MT \
238 else return E_NOINTERFACE; \ 355 else return E_NOINTERFACE; \
239 ++_m_RefCount; /* AddRef(); */ return S_OK; } 356 InterlockedIncrement((LONG *)&_m_RefCount); /* AddRef(); */ return S_OK; }
357
358// you can define Z7_COM_USE_ATOMIC,
359// if you want to call Release() from different threads (for example, for .NET code)
360// #define Z7_COM_USE_ATOMIC
361
362#if defined(Z7_COM_USE_ATOMIC) && !defined(Z7_ST)
363
364#ifndef _WIN32
365#if 0
366#include "../../C/Threads.h"
367#else
368EXTERN_C_BEGIN
369LONG InterlockedIncrement(LONG volatile *addend);
370LONG InterlockedDecrement(LONG volatile *addend);
371EXTERN_C_END
372#endif
373#endif // _WIN32
374
375#define Z7_COM_ADDREF_RELEASE Z7_COM_ADDREF_RELEASE_MT
376#define Z7_COM_QI_END Z7_COM_QI_END_MT
377
378#else // !Z7_COM_USE_ATOMIC
240 379
241#define Z7_COM_ADDREF_RELEASE \ 380#define Z7_COM_ADDREF_RELEASE \
242 private: \ 381 private: \
243 STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \ 382 STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \
244 { return ++_m_RefCount; } \ 383 { return ++_m_RefCount; } \
245 STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \ 384 STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \
246 { if (--_m_RefCount != 0) return _m_RefCount; delete this; return 0; } \ 385 { if (--_m_RefCount != 0) return _m_RefCount; \
386 delete this; return 0; }
387
388#define Z7_COM_QI_END \
389 else return E_NOINTERFACE; \
390 ++_m_RefCount; /* AddRef(); */ return S_OK; }
391
392#endif // !Z7_COM_USE_ATOMIC
393
247 394
248#define Z7_COM_UNKNOWN_IMP_SPEC(i) \ 395#define Z7_COM_UNKNOWN_IMP_SPEC(i) \
249 Z7_COM_QI_BEGIN \ 396 Z7_COM_QI_BEGIN \