Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
p6comptr.h
Go to the documentation of this file.
1 
10 #ifndef P6COMPTR_H__
11 #define P6COMPTR_H__ 1
12 
13 #ifdef __cplusplus
14 namespace P6R {
15 
24  template<typename I>
25  class p6ComPtrNoAddrefRelease : public I
26  {
27  P6NOEXPORT P6R::P6INT32 P6STDCALL addref() = 0;
28  P6NOEXPORT P6R::P6INT32 P6STDCALL release() = 0;
29  };
30 
40  template<typename I> class p6ComPtrBase
41  {
42  protected:
43 
49  p6ComPtrBase(I *pRawPtr = NULL)
50  : m_pRaw(pRawPtr)
51  {
52  if(m_pRaw) { m_pRaw->addref(); }
53  }
54 
56  {
57  //P6R::p6ICom* pTmp = m_pRaw;
58  I* pTmp = m_pRaw;
59 
60  m_pRaw = NULL;
61  if(pTmp) {
62  pTmp->release();
63  }
64  }
65 
66  //private:
67  // This causes compilation errors with stlpd_std::list<> on windows VC++ 2005
68  // We'd like to make this private to prevent people from doing the wrong
69  // thing with address of. Using this operator can cause leaks when p6ComPtr
70  // has already been assigned an interface pointer. The pointer will
71  // not be released before it is potentially overwritten. addressofWithRelease()
72  // should be used instead.
73  //const p6ComPtrBase<I>* operator&() const { return this; }
74 
75  public:
76  typedef I element_type;
77 
79 
80  operator I*() const { return static_cast<I*>(m_pRaw); }
81  I& operator*() const { P6ASSERT(NULL != m_pRaw); return *static_cast<I*>(m_pRaw); }
83  P6BOOL operator==(I* pI) const { return (pI == m_pRaw) ? P6TRUE:P6FALSE; }
84  P6BOOL operator!=(I* pI) const { return (pI != m_pRaw) ? P6TRUE:P6FALSE; }
85  P6BOOL operator<(I* pI) const { return (m_pRaw < pI) ? P6TRUE:P6FALSE; }
86  P6BOOL operator!() const { return (NULL == m_pRaw) ? P6TRUE:P6FALSE; }
87 
88  inline I** addressof()
89  {
90  return reinterpret_cast<I**>(&m_pRaw);
91  }
92 
93  inline I** addressofWithRelease()
94  {
95  release();
96  return reinterpret_cast<I**>(&m_pRaw);
97  }
98 
107  inline P6VOID swap(I** ppIface)
108  {
109  I *tmp = *ppIface;
110  *ppIface = reinterpret_cast<I*>(m_pRaw);
111  m_pRaw = tmp;
112  }
113 
118  {
119  I *tmp = rhs.m_pRaw;
120  rhs.m_pRaw = m_pRaw;
121  m_pRaw = tmp;
122  }
123 
124  inline I* get() const
125  {
126  return reinterpret_cast<I*>(m_pRaw);
127  }
128 
134  void attach(I* pIface)
135  {
136  release();
137  m_pRaw = pIface;
138  }
139 
146  inline I* detach()
147  {
148  I* p = m_pRaw;
149  m_pRaw = NULL;
150  return p;
151  }
152 
161  inline P6VOID detach(I** ppIface)
162  {
163  *ppIface = NULL;
164  swap(ppIface);
165  }
166 
180  inline P6R::P6ERR createInstance(P6R::p6ICom *pOuter,const P6REFCID cid,const P6REFIID riid)
181  {
182  release();
183  return p6CreateInstance(pOuter,cid,riid,reinterpret_cast<P6VOID**>(&m_pRaw));
184  }
185 
196  {
197  release();
198  return p6GetRuntimeIface(riid,reinterpret_cast<P6VOID**>(&m_pRaw));
199  }
200 
214  template<typename Q> P6R::P6ERR queryInterface(const P6REFIID riid,Q** ppIface)
215  {
216  P6ASSERT(NULL != m_pRaw);
217  return m_pRaw->queryInterface(riid,reinterpret_cast<P6VOID**>(ppIface));
218  }
219 
220  protected:
221  I *m_pRaw;
222  };
223 
230  template<typename I> class p6ComPtr : public p6ComPtrBase<I>
231  {
232  public:
233  typedef I element_type;
238  explicit p6ComPtr(I* ip = NULL) : p6ComPtrBase<I>(ip)
239  { }
240 
247  p6ComPtr(const P6REFCID rclsid,const P6REFIID riid,P6R::P6ERR *pErr = NULL) : p6ComPtrBase<I>(NULL)
248  {
249  P6ERR err = p6ComPtrBase<I>::createInstance(NULL,rclsid,riid);
250  P6ASSERT(eOk == err);
251  if(pErr) (*pErr) = err;
252  }
253 
254  p6ComPtr(const P6REFIID riid,P6R::P6ERR *pErr = NULL)
255  {
257  P6ASSERT(eOk == err);
258  if(pErr) (*pErr) = err;
259  }
260 
270  p6ComPtr(p6ICom *pCom,const P6REFIID riid,P6R::P6ERR *pErr = NULL) : p6ComPtrBase<I>(0)
271  {
272  p6ComPtr<I> tmp;
273  P6R::P6ERR err = pCom->queryInterface(riid,(P6VOID**)tmp.addressof());
274  P6ASSERT(eOk == err);
275  if(pErr) (*pErr) = err;
276  if(P6SUCCEEDED(err)) p6ComPtrBase<I>::swap(tmp);
277  }
278 
282  p6ComPtr(const p6ComPtr<I>& rSI) : p6ComPtrBase<I>(rSI.m_pRaw)
283  { }
284 
289  {
290  if(*this != ip) {
291  p6ComPtr<I> tmp(ip);
292  swap(tmp);
293  }
294  return *this;
295  }
296 
301  {
302  if(*this!=cp) {
303  p6ComPtr<I> tmp(cp);
304  swap(tmp);
305  }
306  return *this;
307  }
308  };
309 
315  template<typename Interface>
317  { left.swap(right); }
318 
325  template<> class p6ComPtr<p6ICom> : public p6ComPtrBase<p6ICom>
326  {
327  public:
329 
334  : p6ComPtrBase<p6ICom>(NULL)
335  {
336  }
337 
341  explicit p6ComPtr(p6ICom *pI)
342  : p6ComPtrBase<p6ICom>(pI)
343  {
344  }
345 
349  p6ComPtr(const p6ComPtr<p6ICom> &smartPtr)
350  : p6ComPtrBase<p6ICom>(smartPtr.m_pRaw)
351  {
352  }
353 
354  operator p6ICom*() const
355  {
356  return get();
357  }
358 
363  {
364  if(*this != ip) {
365  p6ComPtr<p6ICom> tmp(ip);
366  swap(tmp);
367  }
368  return *this;
369  }
370 
375  {
376  if(*this!=cp) {
377  p6ComPtr<p6ICom> tmp(cp);
378  swap(tmp);
379  }
380  return *this;
381  }
382  };
383 
384 
428 #define VALIDATECOMPTR(type,smartComPtr) IID_##type, reinterpret_cast<P6R::P6VOID**>(static_cast<type**>((smartComPtr).addressofWithRelease()))
429 
430 
431 } // namespace
432 #endif // __cplusplus
433 
434 #endif
435 
#define P6STDCALL
Definition: p6defs.h:107
#define P6TRUE
Definition: p6types.h:113
A smart pointer implementation to help manage and use [p6]COM based interfaces.
Definition: p6comptr.h:230
P6API P6ERR P6CCALL p6GetRuntimeIface(const P6R::P6IID &iid, P6VOID **ppIface)
This method is used to retreive any of the loader runtime interfaces.
P6VOID swap(p6ComPtr< Interface > &left, p6ComPtr< Interface > &right)
In order for generic algorithms to find p6ComPtr&#39;s swap() implementation, we must also provide a non-...
Definition: p6comptr.h:316
#define P6REFIID
Definition: p6defs.h:181
I ** addressof()
Definition: p6comptr.h:88
p6ComPtrBase(I *pRawPtr=NULL)
Default constructor.
Definition: p6comptr.h:49
I * detach()
Detach the owned inteface from the smart pointer and return a dumb pointer without release() directly...
Definition: p6comptr.h:146
p6ComPtr< I > & operator=(I *ip)
Assign from a dumb pointer of the correct type.
Definition: p6comptr.h:288
unsigned char P6BOOL
Boolean type.
Definition: p6types.h:112
P6R::P6ERR createInstance(P6R::p6ICom *pOuter, const P6R::P6CID &cid, const P6R::P6IID &riid)
Create a new component instance and assign the result to this smart pointer.
Definition: p6comptr.h:180
P6BOOL operator!=(I *pI) const
Definition: p6comptr.h:84
p6ComPtr(const P6R::P6IID &riid, P6R::P6ERR *pErr=NULL)
Definition: p6comptr.h:254
P6VOID swap(p6ComPtrBase< I > &rhs)
Exchange ownership.
Definition: p6comptr.h:117
p6ComPtr(p6ICom *pCom, const P6R::P6IID &riid, P6R::P6ERR *pErr=NULL)
Construct from the specified interface via queryInterface() This will query the interface passed in p...
Definition: p6comptr.h:270
P6VOID detach(I **ppIface)
Detach the owned interface from the smart pointer without release().
Definition: p6comptr.h:161
#define P6NOEXPORT
Definition: p6defs.h:104
I & operator*() const
Definition: p6comptr.h:81
p6ComPtr(p6ICom *pI)
Contruct from a dumb pointer of the correct type.
Definition: p6comptr.h:341
p6ComPtr()
Default constructor.
Definition: p6comptr.h:333
P6ERR(P6CCALL * P6ASSERT)(const P6WCHAR *pszExpr, const P6CHAR *pszFile, P6UINT32 nLine)
Definition: p6dllapi.h:58
I ** addressofWithRelease()
Definition: p6comptr.h:93
void attach(I *pIface)
Take ownership of a new interface without addref().
Definition: p6comptr.h:134
p6ComPtr(const p6ComPtr< I > &rSI)
Copy.
Definition: p6comptr.h:282
P6R::P6ERR getRuntimeIface(const P6R::P6IID &riid)
Get an instance of a runtime interface and adding the result to this smart pointer.
Definition: p6comptr.h:195
virtual P6R::P6ERR queryInterface(const P6R::P6IID &iid, P6VOID **ppIface)=0
This method queries the component for a specific interface.
int P6INT32
Definition: p6types.h:47
The base interface all [p6]COM components must derive from and implement.
Definition: p6comdef.h:97
P6API P6ERR P6CCALL p6CreateInstance(p6ICom *pOuter, const P6R::P6CID &cid, const P6R::P6IID &iid, P6VOID **ppIface)
Creates a single uninitialized instance of the class/interface associated with the specified componen...
p6ComPtr< I > & operator=(const p6ComPtr< I > &cp)
Assign from a smart pointer of the correct type.
Definition: p6comptr.h:300
P6BOOL operator==(I *pI) const
Definition: p6comptr.h:83
A template specialization to support the p6ICom interface.
Definition: p6comptr.h:325
p6ComPtr(I *ip=NULL)
Construct from a raw pointer of the correct type Must be derrived from p6ICom.
Definition: p6comptr.h:238
P6VOID release()
Definition: p6comptr.h:55
p6ComPtrNoAddrefRelease< I > * operator->() const
Definition: p6comptr.h:82
p6ComPtr< p6ICom > & operator=(const p6ComPtr< p6ICom > &cp)
Assign from a smart pointer of the correct type.
Definition: p6comptr.h:374
p6ComPtr< p6ICom > & operator=(p6ICom *ip)
Assign from a dumb pointer of the correct type.
Definition: p6comptr.h:362
P6BOOL operator<(I *pI) const
Definition: p6comptr.h:85
P6UINT32 P6ERR
COM err return type see P6ERR.h.
Definition: p6types.h:120
Base class which implements common functionality for p6ComPtr and it&#39;s p6ICom specialization.
Definition: p6comptr.h:40
P6R::P6ERR queryInterface(const P6R::P6IID &riid, Q **ppIface)
A type safe version of queryInterface().
Definition: p6comptr.h:214
#define P6SUCCEEDED(err)
Definition: p6err.h:49
P6BOOL operator!() const
Definition: p6comptr.h:86
Template used to make the addref() and release() methods inaccessable when dereferncing a p6ComPtr&lt;&gt; ...
Definition: p6comptr.h:25
p6ComPtr(const P6R::P6CID &rclsid, const P6R::P6IID &riid, P6R::P6ERR *pErr=NULL)
Construct a new instance given the component ID and interface ID.
Definition: p6comptr.h:247
#define P6REFCID
Definition: p6defs.h:180
void P6VOID
Definition: p6types.h:88
p6ComPtr(const p6ComPtr< p6ICom > &smartPtr)
Copy constructor.
Definition: p6comptr.h:349
P6VOID swap(I **ppIface)
Exchange ownership.
Definition: p6comptr.h:107
#define P6FALSE
Definition: p6types.h:114