STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ptr.h
Go to the documentation of this file.
1 /***
2 *ptr.h
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose: COM Wrapper for the Managed World
7 *
8 * [Public]
9 *
10 ****/
11 
12 #pragma once
13 
14 #if !defined (_INC_MSCLR_COM_PTR)
15 
16 #ifndef __cplusplus_cli
17 #error ERROR: msclr libraries are not compatible with /clr:oldSyntax
18 #endif /* __cplusplus_cli */
19 
20 #include <vcclr.h>
21 
22 #include <msclr\safebool.h>
23 
24 namespace msclr
25 {
26 
27 namespace _detail
28 {
29  // COM::ptr::operator->() returns a smart_com_ptr instead of
30  // a regular interface pointer so that a Release is done automatically
31  // when the temporary is destroyed
32 
33  template<class _interface_type>
34  ref class smart_com_ptr
35  {
36  public:
37  smart_com_ptr(_interface_type * p)
38  {
39  ptr= p;
40  }
41 
43  {
44  ptr = ip.ptr;
45  ptr->AddRef();
46  }
47 
48  _interface_type * operator ->()
49  {
50  return ptr;
51  }
52 
54  {
55  ptr->Release();
56  }
57 
58  private:
59  _interface_type * ptr;
60  };
61 } //namespace _detail
62 
63 
64 namespace com
65 {
66  template<class _interface_type>
67  ref class ptr
68  {
69  public:
70 
71  ptr():obj_rcw(nullptr)
72  {
73  }
74 
75  // Construct from interface pointer
76  ptr(_interface_type * p)
77  {
78  obj_rcw = nullptr;
79  assign(p);
80  }
81 
82  // Attach to an interface pointer
83  void Attach(_interface_type * _right)
84  {
85  if (valid())
86  {
87  throw gcnew System::InvalidOperationException("COM::ptr.Attach");
88  }
89 
90  assign(_right);
91  }
92 
93  // Assign an interface pointer
94  ptr<_interface_type> % operator=(_interface_type * _right)
95  {
96  Attach(_right);
97  return *this;
98  }
99 
100  // All CreateInstance methods create an instance of a COM Object
101  // by calling CoCreateInstance
102  void CreateInstance(System::String ^ prog_id, LPUNKNOWN pouter, DWORD cls_context)
103  {
104  wchar_t * pwszprog_id = NULL;
105 
106  if(prog_id != nullptr)
107  {
108  pin_ptr<const __wchar_t> _pinned_ptr = PtrToStringChars( prog_id );
109  pwszprog_id = _wcsdup(_pinned_ptr);
110  }
111 
112  try
113  {
114  CreateInstance(pwszprog_id, pouter, cls_context);
115  }
116  finally
117  {
118  free(pwszprog_id);
119  }
120  }
121 
122  void CreateInstance(System::String ^ prog_id, LPUNKNOWN pouter)
123  {
124  CreateInstance(prog_id, pouter, CLSCTX_ALL);
125  }
126 
127  void CreateInstance(System::String ^ prog_id)
128  {
129  CreateInstance(prog_id, NULL, CLSCTX_ALL);
130  }
131 
132  void CreateInstance(const wchar_t* progid, LPUNKNOWN pouter, DWORD cls_context)
133  {
134  CLSID clsid;
135  System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(
136  CLSIDFromProgID(progid, &clsid));
137  CreateInstance(clsid, pouter, cls_context);
138  }
139 
140  void CreateInstance(const wchar_t * progid, LPUNKNOWN pouter)
141  {
142  CreateInstance(progid, pouter, CLSCTX_ALL);
143  }
144 
145  void CreateInstance(const wchar_t * progid)
146  {
147  CreateInstance(progid, NULL, CLSCTX_ALL);
148  }
149 
150  void CreateInstance(REFCLSID rclsid,LPUNKNOWN pouter,DWORD cls_context)
151  {
152  if (valid())
153  {
154  throw gcnew System::InvalidOperationException("COM::ptr.CreateInstance");
155  }
156 
157  _interface_type * interface_ptr = NULL;
158 
159  System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(CoCreateInstance(
160  rclsid, pouter, cls_context, __uuidof(_interface_type),
161  (void**)&interface_ptr));
162 
163  if (interface_ptr)
164  {
165  assign(interface_ptr);
166  interface_ptr->Release();
167  }
168  }
169 
170  void CreateInstance(REFCLSID rclsid,LPUNKNOWN pouter)
171  {
172  CreateInstance(rclsid, pouter, CLSCTX_ALL);
173  }
174 
175  void CreateInstance(REFCLSID rclsid)
176  {
177  CreateInstance(rclsid, NULL, CLSCTX_ALL);
178  }
179 
180  // Give up ownership of the interface pointer & return the
181  // interface pointer
182  _interface_type * Detach()
183  {
184  if(valid())
185  {
186  _interface_type * interface_ptr = GetInterface();
187  destroy();
188  return interface_ptr;
189  }
190 
191  return NULL;
192  }
193 
194  // Give up ownership of the interface pointer
195  void Release()
196  {
197  if(valid())
198  {
199  destroy();
200  }
201  }
202 
203  // Operator ->() - to be used to call methods on the owned COM Object
204  // We return a smart_com_ptr instead of an interface pointer so that
205  // the reference is released automatically
207  {
209  return interface_ptr;
210  }
211 
212  // Return an interface pointer
213  _interface_type * GetInterface()
214  {
215  if(!valid())
216  {
217  return NULL;
218  }
219 
220  System::IntPtr iface_intptr = System::Runtime::InteropServices::Marshal::GetIUnknownForObject(obj_rcw);
221 
222  IUnknown * iunk = static_cast<IUnknown *>(static_cast<void*>(iface_intptr));
223 
224  _interface_type * interface_ptr;
225  System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(iunk->QueryInterface(__uuidof(_interface_type), (void **)&interface_ptr));
226 
227  iunk->Release();
228 
229  interface_ptr->AddRef();
230  System::Runtime::InteropServices::Marshal::Release(iface_intptr);
231 
232  return interface_ptr;
233  }
234 
235  // QueryInteface & fillup up the passed it COM::ptr with the result
236  template<class _other_type>
238  {
239  QueryInterface<_other_type>(__uuidof(_other_type), other);
240  }
241 
242  // for use when com::ptr appears in a conditional
244  {
246  }
247 
248  // for use when com::ptr appears in a conditional
249  bool operator!()
250  {
251  return ! valid();
252  }
253 
255  {
256  if(valid())
257  {
258  destroy();
259  }
260  }
261 
262  private:
263 
264  void destroy()
265  {
266  System::Runtime::InteropServices::Marshal::ReleaseComObject(obj_rcw);
267  obj_rcw = nullptr;
268  }
269 
270  bool valid()
271  {
272  return (obj_rcw != nullptr);
273  }
274 
275 
276  void assign(_interface_type *p)
277  {
278  if(p)
279  {
280  obj_rcw = System::Runtime::InteropServices::Marshal::GetUniqueObjectForIUnknown(System::IntPtr(p));
281  }
282  }
283 
284  template<class _other_type>
286  {
288  _other_type * other_ptr;
289 
290  System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(interface_ptr->QueryInterface(riid,(void **)&other_ptr));
291  other.Attach(other_ptr);
292 
293  other_ptr->Release();
294  }
295 
296  Object ^obj_rcw;
297  };
298 } // namespace com
299 
300 } // namespace msclr
301 
302 #define _INC_MSCLR_COM_PTR
303 #endif /* !defined (_INC_MSCLR_COM_PTR) */
smart_com_ptr(_interface_type *p)
Definition: ptr.h:37
_interface_type * operator->()
Definition: ptr.h:48
System::String _safe_bool
Definition: safebool.h:37
void CreateInstance(System::String^prog_id, LPUNKNOWN pouter)
Definition: ptr.h:122
void CreateInstance(const wchar_t *progid, LPUNKNOWN pouter, DWORD cls_context)
Definition: ptr.h:132
ptr()
Definition: ptr.h:71
Definition: appdomain.h:36
void assign(_interface_type *p)
Definition: ptr.h:276
static _safe_bool const _safe_false
Definition: safebool.h:39
_CRTIMP _CRTNOALIAS void __cdecl free(_Pre_maybenull_ _Post_invalid_ void *_Memory)
#define NULL
Definition: crtdbg.h:30
__const_Char_ptr PtrToStringChars(__const_String_handle s)
Definition: vcclr.h:40
void CreateInstance(REFCLSID rclsid)
Definition: ptr.h:175
static _safe_bool const _safe_true
Definition: safebool.h:38
~smart_com_ptr()
Definition: ptr.h:53
Object obj_rcw
Definition: ptr.h:296
Definition: ptr.h:67
void Release()
Definition: ptr.h:195
void Attach(_interface_type *_right)
Definition: ptr.h:83
_interface_type * ptr
Definition: ptr.h:59
Definition: ptr.h:34
void CreateInstance(REFCLSID rclsid, LPUNKNOWN pouter, DWORD cls_context)
Definition: ptr.h:150
void destroy()
Definition: ptr.h:264
_interface_type * GetInterface()
Definition: ptr.h:213
REFIID
Definition: agile.h:27
ptr< _interface_type > operator=(_interface_type *_right)
Definition: ptr.h:94
unsigned long DWORD
Definition: concrt.h:57
~ptr()
Definition: ptr.h:254
void CreateInstance(REFCLSID rclsid, LPUNKNOWN pouter)
Definition: ptr.h:170
void CreateInstance(System::String^prog_id, LPUNKNOWN pouter, DWORD cls_context)
Definition: ptr.h:102
bool operator!()
Definition: ptr.h:249
bool valid()
Definition: ptr.h:270
void CreateInstance(const wchar_t *progid, LPUNKNOWN pouter)
Definition: ptr.h:140
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
smart_com_ptr(smart_com_ptr%ip)
Definition: ptr.h:42
_interface_type * Detach()
Definition: ptr.h:182
void QueryInterface(ptr< _other_type >%other)
Definition: ptr.h:237
_detail::smart_com_ptr< _interface_type > operator->()
Definition: ptr.h:206
void CreateInstance(System::String^prog_id)
Definition: ptr.h:127
ptr(_interface_type *p)
Definition: ptr.h:76
void QueryInterface(REFIID riid, ptr< _other_type >%other)
Definition: ptr.h:285
void CreateInstance(const wchar_t *progid)
Definition: ptr.h:145