Changeset 30632 in vbox for trunk/include/VBox/com
- Timestamp:
- Jul 5, 2010 7:36:40 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 63367
- Location:
- trunk/include/VBox/com
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/com.h
r28800 r30632 57 57 * @param aName Resolved interface name or @c NULL on error 58 58 */ 59 void GetInterfaceNameByIID (const GUID &aIID, BSTR *aName); 59 void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName); 60 61 #ifdef VBOX_WITH_XPCOM 62 63 /** 64 * Helper method to keep all the XPCOM headers out of include/VBox/com/ptr.h. 65 */ 66 HRESULT GlueCreateObjectOnServer(const CLSID &clsid, 67 const char *serverName, 68 const nsIID &id, 69 void** ppobj); 70 71 /** 72 * Helper method to keep all the XPCOM headers out of include/VBox/com/ptr.h. 73 */ 74 HRESULT GlueCreateInstance(const CLSID &clsid, 75 const nsIID &id, 76 void** ppobj); 77 78 #endif // VBOX_WITH_XPCOM 60 79 61 80 /** -
trunk/include/VBox/com/ptr.h
r29931 r30632 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 37 37 38 38 #if !defined (VBOX_WITH_XPCOM) 39 40 #include <atlbase.h> 41 42 #ifndef _ATL_IIDOF 43 # define _ATL_IIDOF(c) __uuidof(c) 44 #endif 45 46 #else /* !defined (VBOX_WITH_XPCOM) */ 47 48 #include <nsXPCOM.h> 49 #include <nsIComponentManager.h> 50 #include <nsCOMPtr.h> 51 #include <ipcIService.h> 52 #include <nsIServiceManagerUtils.h> 53 #include <ipcCID.h> 54 #include <ipcIDConnectService.h> 55 56 // official XPCOM headers don't define it yet 57 #define IPC_DCONNECTSERVICE_CONTRACTID \ 58 "@mozilla.org/ipc/dconnect-service;1" 59 39 #include <atlbase.h> 40 #ifndef _ATL_IIDOF 41 # define _ATL_IIDOF(c) __uuidof(c) 42 #endif 43 #else 44 #include <nsISupportsUtils.h> 60 45 #endif /* !defined (VBOX_WITH_XPCOM) */ 61 46 62 #include <VBox/com/defs.h> 63 #include <VBox/com/assert.h> 64 65 #define LOGREF(prefix, pObj, cRefs) com::LogRef("%s {%p} cRefs=%d\n", (prefix), (pObj), (cRefs)) 66 67 namespace com 68 { 69 void LogRef(const char *pcszFormat, ...); 70 } 47 #include <VBox/com/com.h> 71 48 72 49 /** 73 * Returns @c true if two interface pointers are equal. 74 * 75 * According to the COM Identity Rule, interface pointers are considered to be 76 * equal if and only if IUnknown pointers queried on these interfaces pointers 77 * are equal (e.g. have the same binary value). Equal interface pointers 78 * represent the same object even if they are pointers to different interfaces. 79 * 80 * @param I1 Class of the first interface pointer (must be derived from 81 * IUnknown). 82 * @param I2 Class of the second interface pointer (must be derived from 83 * IUnknown). 50 * COM autopointer class which takes care of all required reference counting. 51 * 52 * This automatically calls the required basic COM methods on COM pointers 53 * given to it: 54 * 55 * -- AddRef() gets called automatically whenever a new COM pointer is assigned 56 * to the ComPtr instance (either in the copy constructor or by assignment); 57 * 58 * -- Release() gets called automatically by the destructor and when an existing 59 * object gets released in assignment; 60 * 61 * -- QueryInterface() gets called automatically when COM pointers get converted 62 * from one interface to another. 63 * 64 * Example usage: 65 * 66 * @code 67 * 68 * { 69 * ComPtr<IMachine> pMachine = findMachine("blah"); // calls AddRef() 70 * ComPtr<IUnknown> pUnknown = pMachine; // calls QueryInterface() 71 * } # ComPtr destructor of both instances calls Release() 72 * 73 * @endcode 84 74 */ 85 template <class I1, class I2> 86 inline bool ComPtrEquals(I1 *aThis, I2 *aThat) 87 { 88 IUnknown *thatUnk = NULL, *thisUnk = NULL; 89 if (aThat) 90 aThat->QueryInterface(COM_IIDOF(IUnknown), (void**)&thatUnk); 91 if (aThis) 92 aThis->QueryInterface(COM_IIDOF(IUnknown), (void**)&thisUnk); 93 bool equal = (thisUnk == thatUnk); 94 if (thisUnk) 95 thisUnk->Release(); 96 if (thatUnk) 97 thatUnk->Release(); 98 return equal; 99 } 100 101 /* specialization for <Any, IUnknown> */ 102 template <class I1> 103 inline bool ComPtrEquals(I1 *aThis, IUnknown *aThat) 104 { 105 IUnknown *thisUnk = NULL; 106 if (aThis) 107 aThis->QueryInterface(COM_IIDOF(IUnknown), (void**)&thisUnk); 108 bool equal = (thisUnk == aThat); 109 if (thisUnk) 110 thisUnk->Release(); 111 return equal; 112 } 113 114 /** Specialization for <IUnknown, Any> */ 115 template <class I2> 116 inline bool ComPtrEquals(IUnknown *aThis, I2 *aThat) 117 { 118 IUnknown *thatUnk = NULL; 119 if (aThat) 120 aThat->QueryInterface(COM_IIDOF(IUnknown), (void**)&thatUnk); 121 bool equal = (aThis == thatUnk); 122 if (thatUnk) 123 thatUnk->Release(); 124 return equal; 125 } 126 127 /* specialization for IUnknown */ 128 template<> 129 inline bool ComPtrEquals<IUnknown, IUnknown>(IUnknown *aThis, IUnknown *aThat) 130 { 131 return aThis == aThat; 132 } 133 134 /** 135 * Base template for smart COM pointers. Not intended to be used directly. 136 */ 137 template <class C> 138 class ComPtrBase 75 template <class T> 76 class ComPtr 139 77 { 140 78 public: 141 79 142 /* special template to disable AddRef()/Release() */ 143 template <class I> 144 class NoAddRefRelease : public I 145 { 146 private: 147 #if !defined (VBOX_WITH_XPCOM) 148 STDMETHOD_(ULONG, AddRef)() = 0; 149 STDMETHOD_(ULONG, Release)() = 0; 150 #else /* !defined (VBOX_WITH_XPCOM) */ 151 NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; 152 NS_IMETHOD_(nsrefcnt) Release(void) = 0; 153 #endif /* !defined (VBOX_WITH_XPCOM) */ 154 }; 155 156 protected: 157 158 ComPtrBase() 159 : p(NULL) 160 {} 161 162 ComPtrBase(const ComPtrBase &that) 163 : p(that.p) 164 { 165 addref(); 166 } 167 168 ComPtrBase(C *that_p) 169 : p(that_p) 170 { 171 addref(); 172 } 173 174 ~ComPtrBase() 175 { 176 release(); 177 } 178 179 ComPtrBase &operator=(const ComPtrBase &that) 180 { 181 safe_assign(that.p); 80 /** 81 * Default constructor, sets up a NULL pointer. 82 */ 83 ComPtr() 84 : m_p(NULL) 85 { } 86 87 /** 88 * Destructor. Calls Release() on the contained COM object. 89 */ 90 ~ComPtr() 91 { 92 cleanup(); 93 } 94 95 /** 96 * Copy constructor from another ComPtr of any interface. 97 * 98 * This calls QueryInterface(T) and can result in a NULL pointer if the input 99 * pointer p does not support the ComPtr interface T. 100 * 101 * Does not call AddRef explicitly because if QueryInterface succeeded, then 102 * the refcount will have been increased by one already . 103 */ 104 template <class T2> 105 ComPtr(const ComPtr<T2> &that) 106 { 107 m_p = NULL; 108 if (!that.isNull()) 109 that->QueryInterface(COM_IIDOF(T), (void**)&m_p); 110 } 111 112 /** 113 * Specialization: copy constructor from another ComPtr<T>. Calls AddRef(). 114 */ 115 ComPtr(const ComPtr &that) 116 { 117 copyFrom(that.m_p); 118 } 119 120 /** 121 * Copy constructor from another interface pointer of any interface. 122 * 123 * This calls QueryInterface(T) and can result in a NULL pointer if the input 124 * pointer p does not support the ComPtr interface T. 125 * 126 * Does not call AddRef explicitly because if QueryInterface succeeded, then 127 * the refcount will have been increased by one already . 128 */ 129 template <class T2> 130 ComPtr(T2 *p) 131 { 132 m_p = NULL; 133 if (p) 134 p->QueryInterface(COM_IIDOF(T), (void**)&m_p); 135 } 136 137 /** 138 * Specialization: copy constructor from a plain T* pointer. Calls AddRef(). 139 */ 140 ComPtr(T *that_p) 141 { 142 copyFrom(that_p); 143 } 144 145 /** 146 * Assignment from another ComPtr of any interface. 147 * 148 * This calls QueryInterface(T) and can result in a NULL pointer if the input 149 * pointer p does not support the ComPtr interface T. 150 * 151 * Does not call AddRef explicitly because if QueryInterface succeeded, then 152 * the refcount will have been increased by one already . 153 */ 154 template <class T2> 155 ComPtr& operator=(const ComPtr<T2> &that) 156 { 157 return operator=((T2*)that); 158 } 159 160 /** 161 * Specialization of the previous: assignment from another ComPtr<T>. 162 * Calls Release() on the previous member pointer, if any, and AddRef() on the new one. 163 */ 164 ComPtr& operator=(const ComPtr &that) 165 { 166 return operator=((T*)that); 167 } 168 169 /** 170 * Assignment from another interface pointer of any interface. 171 * 172 * This calls QueryInterface(T) and can result in a NULL pointer if the input 173 * pointer p does not support the ComPtr interface T. 174 * 175 * Does not call AddRef explicitly because if QueryInterface succeeded, then 176 * the refcount will have been increased by one already . 177 */ 178 template <class T2> 179 ComPtr& operator=(T2 *p) 180 { 181 cleanup(); 182 if (p) 183 p->QueryInterface(COM_IIDOF(T), (void**)&m_p); 182 184 return *this; 183 185 } 184 186 185 ComPtrBase &operator=(C *that_p) 186 { 187 safe_assign(that_p); 187 /** 188 * Specialization of the previous: assignment from a plain T* pointer. 189 * Calls Release() on the previous member pointer, if any, and AddRef() on the new one. 190 */ 191 ComPtr& operator=(T *p) 192 { 193 cleanup(); 194 copyFrom(p); 188 195 return *this; 189 196 } 190 197 191 public: 192 198 /** 199 * Resets the ComPtr to NULL. Works like a NULL assignment except it avoids the templates. 200 */ 193 201 void setNull() 194 202 { 195 release(); 196 p = NULL; 197 } 198 203 cleanup(); 204 } 205 206 /** 207 * Returns true if the pointer is NULL. 208 */ 199 209 bool isNull() const 200 210 { 201 return (p == NULL); 202 } 203 204 bool isNotNull() const 205 { 206 return (p != NULL); 207 } 208 209 bool operator!() const { return isNull(); } 210 211 bool operator<(C* that_p) const { return p < that_p; } 212 bool operator==(C* that_p) const { return p == that_p; } 213 214 template <class I> 215 bool equalsTo(I *aThat) const 216 { 217 return ComPtrEquals(p, aThat); 218 } 219 220 template <class OC> 221 bool equalsTo(const ComPtrBase <OC> &oc) const 222 { 223 return equalsTo((OC*)oc); 224 } 225 226 /** Intended to pass instances as in parameters to interface methods */ 227 operator C*() const { return p; } 211 return (m_p == NULL); 212 } 213 214 bool operator<(T* p) const 215 { 216 return m_p < p; 217 } 218 219 /** 220 * Conversion operator, most often used to pass ComPtr instances as 221 * parameters to COM method calls. 222 */ 223 operator T*() const 224 { 225 return m_p; 226 } 228 227 229 228 /** … … 231 230 * pointer). 232 231 */ 233 #ifndef IN_SLICKEDIT 234 NoAddRefRelease<C>* operator->() const 235 { 236 AssertMsg(p, ("Managed pointer must not be null\n")); 237 return (NoAddRefRelease<C>*)p; 238 } 239 #else /* IN_SLICKEDIT - The editor doesn't quite grok the above magic, sorry about the mess. */ 240 C *operator->() const { return this->p; } 241 #endif 242 243 template <class I> 244 HRESULT queryInterfaceTo(I **pp) const 232 T* operator->() const 233 { 234 return m_p; 235 } 236 237 /** 238 * Special method which allows using a ComPtr as an output argument of a COM method. 239 * The ComPtr will then accept the method's interface pointer without calling AddRef() 240 * itself, since by COM convention this must has been done by the method which created 241 * the object that is being accepted. 242 * 243 * The ComPtr destructor will then still invoke Release() so that the returned object 244 * can get cleaned up properly. 245 */ 246 T** asOutParam() 247 { 248 cleanup(); 249 return &m_p; 250 } 251 252 /** 253 * Converts the contained pointer to a different interface 254 * by calling QueryInterface() on it. 255 * @param pp 256 * @return 257 */ 258 template <class T2> 259 HRESULT queryInterfaceTo(T2 **pp) const 245 260 { 246 261 if (pp) 247 262 { 248 if (p) 249 { 250 return p->QueryInterface(COM_IIDOF(I), (void**)pp); 251 } 263 if (m_p) 264 return m_p->QueryInterface(COM_IIDOF(T2), (void**)pp); 252 265 else 253 266 { … … 260 273 } 261 274 262 /** Intended to pass instances as out parameters to interface methods */ 263 C **asOutParam() 264 { 265 setNull(); 266 return &p; 267 } 268 269 private: 270 271 void addref() 272 { 275 /** 276 * Equality test operator. By COM definition, two COM objects are considered 277 * equal if their IUnknown interface pointers are equal. 278 */ 279 template <class T2> 280 bool operator==(T2* p) 281 { 282 IUnknown *p1 = NULL; 283 bool fNeedsRelease1 = false; 284 if (m_p) 285 fNeedsRelease1 = (SUCCEEDED(m_p->QueryInterface(COM_IIDOF(IUnknown), (void**)&p1))); 286 287 IUnknown *p2 = NULL; 288 bool fNeedsRelease2 = false; 273 289 if (p) 274 p->AddRef(); 275 } 276 277 void release() 278 { 279 if (p) 280 p->Release(); 281 } 282 283 void safe_assign (C *that_p) 284 { 285 /* be aware of self-assignment */ 286 if (that_p) 287 that_p->AddRef(); 288 release(); 289 p = that_p; 290 } 291 292 C *p; 293 }; 294 295 /** 296 * Smart COM pointer wrapper that automatically manages refcounting of 297 * interface pointers. 298 * 299 * @param I COM interface class 300 */ 301 template <class I> 302 class ComPtr : public ComPtrBase<I> 303 { 304 typedef ComPtrBase<I> Base; 305 306 public: 307 308 ComPtr() : Base() {} 309 ComPtr(const ComPtr &that) : Base(that) {} 310 ComPtr& operator=(const ComPtr &that) 311 { 312 Base::operator= (that); 313 return *this; 314 } 315 316 template <class OI> 317 ComPtr(OI *that_p) : Base() { operator=(that_p); } 318 319 /* specialization for I */ 320 ComPtr(I *that_p) : Base(that_p) {} 321 322 template <class OC> 323 ComPtr(const ComPtr<OC> &oc) : Base() { operator=((OC*)oc); } 324 325 template <class OI> 326 ComPtr &operator=(OI *that_p) 327 { 328 if (that_p) 329 that_p->QueryInterface(COM_IIDOF(I), (void**)Base::asOutParam()); 330 else 331 Base::setNull(); 332 return *this; 333 } 334 335 /* specialization for I */ 336 ComPtr &operator=(I *that_p) 337 { 338 Base::operator=(that_p); 339 return *this; 340 } 341 342 template <class OC> 343 ComPtr &operator=(const ComPtr<OC> &oc) 344 { 345 return operator=((OC*)oc); 290 fNeedsRelease2 = (SUCCEEDED(p->QueryInterface(COM_IIDOF(IUnknown), (void**)&p2))); 291 292 bool f = p1 == p2; 293 if (fNeedsRelease1) 294 p1->Release(); 295 if (fNeedsRelease2) 296 p2->Release(); 297 return f; 346 298 } 347 299 … … 350 302 * manage a reference to the created object in case of success. 351 303 */ 352 HRESULT createInprocObject 304 HRESULT createInprocObject(const CLSID &clsid) 353 305 { 354 306 HRESULT rc; 355 I*obj = NULL;307 T *obj = NULL; 356 308 #if !defined (VBOX_WITH_XPCOM) 357 rc = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, _ATL_IIDOF( I),309 rc = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, _ATL_IIDOF(T), 358 310 (void**)&obj); 359 311 #else /* !defined (VBOX_WITH_XPCOM) */ 360 nsCOMPtr<nsIComponentManager> manager; 361 rc = NS_GetComponentManager(getter_AddRefs(manager)); 362 if (SUCCEEDED(rc)) 363 rc = manager->CreateInstance(clsid, nsnull, NS_GET_IID(I), 364 (void **) &obj); 312 using namespace com; 313 rc = GlueCreateInstance(clsid, NS_GET_IID(T), (void**)&obj); 365 314 #endif /* !defined (VBOX_WITH_XPCOM) */ 366 315 *this = obj; … … 383 332 #if !defined (VBOX_WITH_XPCOM) 384 333 HRESULT rc; 385 I*obj = NULL;386 rc = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, _ATL_IIDOF( I),334 T *obj = NULL; 335 rc = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, _ATL_IIDOF(T), 387 336 (void**)&obj); 388 337 *this = obj; … … 404 353 HRESULT createObjectOnServer(const CLSID &clsid, const char *serverName) 405 354 { 406 HRESULT rc; 407 I *obj = NULL; 408 nsCOMPtr<ipcIService> ipcServ = do_GetService(IPC_SERVICE_CONTRACTID, &rc); 409 if (SUCCEEDED(rc)) 410 { 411 PRUint32 serverID = 0; 412 rc = ipcServ->ResolveClientName(serverName, &serverID); 413 if (SUCCEEDED (rc)) 414 { 415 nsCOMPtr<ipcIDConnectService> dconServ = do_GetService(IPC_DCONNECTSERVICE_CONTRACTID, &rc); 416 if (SUCCEEDED(rc)) 417 rc = dconServ->CreateInstance(serverID, clsid, NS_GET_IID(I), 418 (void**)&obj); 419 } 420 } 355 T *obj = NULL; 356 HRESULT rc = GlueCreateObjectOnServer(clsid, serverName, NS_GET_IID(T), (void**)&obj); 421 357 *this = obj; 422 358 if (SUCCEEDED(rc)) … … 425 361 } 426 362 #endif 363 364 protected: 365 void copyFrom(T* p) 366 { 367 if ((m_p = p)) 368 m_p->AddRef(); 369 } 370 371 void cleanup() 372 { 373 if (m_p) 374 { 375 m_p->Release(); 376 m_p = NULL; 377 } 378 } 379 380 T *m_p; 427 381 }; 428 382 429 383 /** 430 * Specialization of ComPtr<> for IUnknown to guarantee identity 431 * by always doing QueryInterface() when constructing or assigning from 432 * another interface pointer disregarding its type. 384 * ComObjPtr is a more specialized variant of ComPtr designed to be used for implementation 385 * objects. For example, use ComPtr<IMachine> for a client pointer that calls the interface 386 * but ComObjPtr<Machine> for a pointer to an implementation object. 387 * 388 * The methods behave the same except that ComObjPtr has the additional createObject() 389 * method which allows for instantiating a new implementation object. 433 390 */ 434 template <>435 class Com Ptr<IUnknown> : public ComPtrBase<IUnknown>391 template <class T> 392 class ComObjPtr : public ComPtr<T> 436 393 { 437 typedef ComPtrBase<IUnknown> Base;438 439 394 public: 440 395 441 ComPtr() : Base() {} 442 ComPtr(const ComPtr &that) : Base (that) {} 443 ComPtr& operator=(const ComPtr &that) 444 { 445 Base::operator=(that); 396 ComObjPtr() 397 : ComPtr<T>() 398 {} 399 400 ComObjPtr(const ComObjPtr &that) 401 : ComPtr<T>(that) 402 {} 403 404 ComObjPtr(T *that_p) 405 : ComPtr<T>(that_p) 406 {} 407 408 ComObjPtr& operator=(const ComObjPtr &that) 409 { 410 ComPtr<T>::operator=(that); 446 411 return *this; 447 412 } 448 413 449 template <class OI> 450 ComPtr(OI *that_p) : Base() { operator=(that_p); } 451 452 template <class OC> 453 ComPtr(const ComPtr<OC> &oc) : Base() { operator=((OC*)oc); } 454 455 template <class OI> 456 ComPtr &operator=(OI *that_p) 457 { 458 if (that_p) 459 that_p->QueryInterface(COM_IIDOF(IUnknown), (void**)Base::asOutParam()); 460 else 461 Base::setNull(); 414 ComObjPtr& operator=(T *that_p) 415 { 416 ComPtr<T>::operator=(that_p); 462 417 return *this; 463 418 } 464 465 template <class OC>466 ComPtr &operator=(const ComPtr<OC> &oc)467 {468 return operator=((OC*)oc);469 }470 };471 472 /**473 * Smart COM pointer wrapper that automatically manages refcounting of474 * pointers to interface implementation classes created on the component's475 * (i.e. the server's) side. Differs from ComPtr by providing additional476 * platform independent operations for creating new class instances.477 *478 * @param C class that implements some COM interface479 */480 template <class C>481 class ComObjPtr : public ComPtrBase<C>482 {483 typedef ComPtrBase<C> Base;484 485 public:486 487 ComObjPtr() : Base() {}488 ComObjPtr(const ComObjPtr &that) : Base(that) {}489 ComObjPtr(C *that_p) : Base(that_p) {}490 491 ComObjPtr& operator=(const ComObjPtr &that)492 {493 Base::operator=(that);494 return *this;495 }496 497 ComObjPtr& operator=(C *that_p)498 {499 Base::operator=(that_p);500 return *this;501 }502 503 #ifdef IN_SLICKEDIT /* Doesn't fully grok the stuff otherwise, sorry for the bloat. */504 C *operator->() const { return this->p; }505 #endif506 419 507 420 /** … … 510 423 * previous pointer, if any, is of course released when appropriate). 511 424 * 512 * @note This method should be used with care on weakly referenced513 * smart pointers because it leaves the newly created object completely514 * unreferenced (i.e., with reference count equal to zero),515 *516 425 * @note Win32: when VBOX_COM_OUTOFPROC_MODULE is defined, the created 517 426 * object doesn't increase the lock count of the server module, as it … … 523 432 #if !defined (VBOX_WITH_XPCOM) 524 433 # ifdef VBOX_COM_OUTOFPROC_MODULE 525 CComObjectNoLock< C> *obj = new CComObjectNoLock<C>();434 CComObjectNoLock<T> *obj = new CComObjectNoLock<T>(); 526 435 if (obj) 527 436 { … … 533 442 rc = E_OUTOFMEMORY; 534 443 # else 535 CComObject< C> *obj = NULL;536 rc = CComObject< C>::CreateInstance(&obj);444 CComObject<T> *obj = NULL; 445 rc = CComObject<T>::CreateInstance(&obj); 537 446 # endif 538 447 #else /* !defined (VBOX_WITH_XPCOM) */ 539 CComObject< C> *obj = new CComObject<C>();448 CComObject<T> *obj = new CComObject<T>(); 540 449 if (obj) 541 450 rc = obj->FinalConstruct();
Note:
See TracChangeset
for help on using the changeset viewer.