VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/include/COMDefs.h@ 16083

Last change on this file since 16083 was 15051, checked in by vboxsync, 16 years ago

Main: Cleaned up the long standing const BSTR = const (OLECHAR *) on WIn32 vs (const PRunichar) * on XPCOM clash. Cleaned up BSTR/GUID macros (IN_BSTR replaces INPTR BSTR, IN_GUID replaces INPTR GUIDPARAM, OUT_GUID replaces GUIDPARAMOUT).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.6 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * Various COM definitions and COM wrapper class declarations
5 *
6 * This header is used in conjunction with the header generated from
7 * XIDL expressed interface definitions to provide cross-platform Qt-based
8 * interface wrapper classes.
9 */
10
11/*
12 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
13 *
14 * This file is part of VirtualBox Open Source Edition (OSE), as
15 * available from http://www.virtualbox.org. This file is free software;
16 * you can redistribute it and/or modify it under the terms of the GNU
17 * General Public License (GPL) as published by the Free Software
18 * Foundation, in version 2 as it comes in the "COPYING" file of the
19 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
20 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
23 * Clara, CA 95054 USA or visit http://www.sun.com if you need
24 * additional information or have any questions.
25 */
26
27#ifndef __COMDefs_h__
28#define __COMDefs_h__
29
30/** @defgroup grp_QT_COM Qt-COM Support Layer
31 * @{
32 *
33 * The Qt-COM support layer provides a set of defintions and smart classes for
34 * writing simple, clean and platform-independent code to access COM/XPCOM
35 * components through exposed COM interfaces. This layer is based on the
36 * COM/XPCOM Abstarction Layer library (the VBoxCOM glue library defined in
37 * include/VBox/com and implemented in src/VBox/Main/glue).
38 *
39 * ...
40 *
41 * @defgroup grp_QT_COM_arrays Arrays
42 * @{
43 *
44 * COM/XPCOM arrays are mapped to QValueVector objects. QValueVector templates
45 * declared with a type that corresponds to the COM type of elements in the
46 * array using normal Qt-COM type mapping rules. Here is a code example that
47 * demonstrates how to call interface methods that take and return arrays (this
48 * example is based on examples given in @ref grp_COM_arrays):
49 * @code
50
51 CSomething component;
52
53 // ...
54
55 QValueVector <LONG> in (3);
56 in [0] = -1;
57 in [1] = -2;
58 in [2] = -3;
59
60 QValueVector <LONG> out;
61 QValueVector <LONG> ret;
62
63 ret = component.TestArrays (in, out);
64
65 for (size_t i = 0; i < ret.size(); ++ i)
66 LogFlow (("*** ret[%u]=%d\n", i, ret [i]));
67
68 * @endcode
69 * @}
70 */
71
72/* Both VBox/com/assert.h and qglobal.h contain a definition of ASSERT.
73 * Either of them can be already included here, so try to shut them up. */
74#undef ASSERT
75
76#include <VBox/com/com.h>
77#include <VBox/com/array.h>
78#include <VBox/com/assert.h>
79
80#undef ASSERT
81
82#include <qglobal.h>
83#include <qstring.h>
84#include <quuid.h>
85#include <qvaluevector.h>
86
87#include <iprt/memory> // for auto_copy_ptr
88
89/*
90 * Additional COM / XPCOM defines and includes
91 */
92
93#if !defined (VBOX_WITH_XPCOM)
94
95#else /* !defined (VBOX_WITH_XPCOM) */
96
97#include <nsXPCOM.h>
98#include <nsMemory.h>
99#include <nsIComponentManager.h>
100
101class XPCOMEventQSocketListener;
102
103#endif /* !defined (VBOX_WITH_XPCOM) */
104
105
106/* VirtualBox interfaces declarations */
107#if !defined (VBOX_WITH_XPCOM)
108 #include <VirtualBox.h>
109#else /* !defined (VBOX_WITH_XPCOM) */
110 #include <VirtualBox_XPCOM.h>
111#endif /* !defined (VBOX_WITH_XPCOM) */
112
113#include "VBoxDefs.h"
114
115
116/////////////////////////////////////////////////////////////////////////////
117
118class CVirtualBoxErrorInfo;
119
120/** Represents extended error information */
121class COMErrorInfo
122{
123public:
124
125 COMErrorInfo()
126 : mIsNull (true)
127 , mIsBasicAvailable (false), mIsFullAvailable (false)
128 , mResultCode (S_OK) {}
129
130 COMErrorInfo (const CVirtualBoxErrorInfo &info) { init (info); }
131
132 /* the default copy ctor and assignment op are ok */
133
134 bool isNull() const { return mIsNull; }
135
136 bool isBasicAvailable() const { return mIsBasicAvailable; }
137 bool isFullAvailable() const { return mIsFullAvailable; }
138
139 HRESULT resultCode() const { return mResultCode; }
140 QUuid interfaceID() const { return mInterfaceID; }
141 QString component() const { return mComponent; }
142 QString text() const { return mText; }
143
144 const COMErrorInfo *next() const { return mNext.get(); }
145
146 QString interfaceName() const { return mInterfaceName; }
147 QUuid calleeIID() const { return mCalleeIID; }
148 QString calleeName() const { return mCalleeName; }
149
150private:
151
152 void init (const CVirtualBoxErrorInfo &info);
153 void fetchFromCurrentThread (IUnknown *callee, const GUID *calleeIID);
154
155 static QString getInterfaceNameFromIID (const QUuid &id);
156
157 bool mIsNull : 1;
158 bool mIsBasicAvailable : 1;
159 bool mIsFullAvailable : 1;
160
161 HRESULT mResultCode;
162 QUuid mInterfaceID;
163 QString mComponent;
164 QString mText;
165
166 cppx::auto_copy_ptr <COMErrorInfo> mNext;
167
168 QString mInterfaceName;
169 QUuid mCalleeIID;
170 QString mCalleeName;
171
172 friend class COMBaseWithEI;
173};
174
175/////////////////////////////////////////////////////////////////////////////
176
177/**
178 * Base COM class the CInterface template and all wrapper classes are derived
179 * from. Provides common functionality for all COM wrappers.
180 */
181class COMBase
182{
183public:
184
185 static HRESULT InitializeCOM();
186 static HRESULT CleanupCOM();
187
188 /**
189 * Returns the result code of the last interface method called by the
190 * wrapper instance or the result of CInterface::createInstance()
191 * operation.
192 */
193 HRESULT lastRC() const { return mRC; }
194
195#if !defined (VBOX_WITH_XPCOM)
196
197 /** Converts a GUID value to QUuid */
198 static QUuid ToQUuid (const GUID &id)
199 {
200 return QUuid (id.Data1, id.Data2, id.Data3,
201 id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
202 id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
203 }
204
205#else /* !defined (VBOX_WITH_XPCOM) */
206
207 /** Converts a GUID value to QUuid */
208 static QUuid ToQUuid (const nsID &id)
209 {
210 return QUuid (id.m0, id.m1, id.m2,
211 id.m3[0], id.m3[1], id.m3[2], id.m3[3],
212 id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
213 }
214
215#endif /* !defined (VBOX_WITH_XPCOM) */
216
217 /* Arrays of arbitrary types */
218
219 template <typename QT, typename CT>
220 static void ToSafeArray (const QValueVector <QT> &aVec, com::SafeArray <CT> &aArr)
221 {
222 Q_UNUSED (aVec);
223 Q_UNUSED (aArr);
224 AssertMsgFailedReturnVoid (("No conversion!\n"));
225 }
226
227 template <typename CT, typename QT>
228 static void FromSafeArray (const com::SafeArray <CT> &aArr, QValueVector <QT> &aVec)
229 {
230 Q_UNUSED (aArr);
231 Q_UNUSED (aVec);
232 AssertMsgFailedReturnVoid (("No conversion!\n"));
233 }
234
235 template <typename QT, typename CT>
236 static void ToSafeArray (const QValueVector <QT *> &aVec, com::SafeArray <CT *> &aArr)
237 {
238 Q_UNUSED (aVec);
239 Q_UNUSED (aArr);
240 AssertMsgFailedReturnVoid (("No conversion!\n"));
241 }
242
243 template <typename CT, typename QT>
244 static void FromSafeArray (const com::SafeArray <CT *> &aArr, QValueVector <QT *> &aVec)
245 {
246 Q_UNUSED (aArr);
247 Q_UNUSED (aVec);
248 AssertMsgFailedReturnVoid (("No conversion!\n"));
249 }
250
251 /* Arrays of equal types */
252
253 template <typename T>
254 static void ToSafeArray (const QValueVector <T> &aVec, com::SafeArray <T> &aArr)
255 {
256 aArr.reset (aVec.size());
257 size_t i = 0;
258 for (typename QValueVector <T>::const_iterator it = aVec.begin();
259 it != aVec.end(); ++ it, ++ i)
260 aArr [i] = *it;
261 }
262
263 template <typename T>
264 static void FromSafeArray (const com::SafeArray <T> &aArr, QValueVector <T> &aVec)
265 {
266 aVec = QValueVector <T> (aArr.size());
267 size_t i = 0;
268 for (typename QValueVector <T>::iterator it = aVec.begin();
269 it != aVec.end(); ++ it, ++ i)
270 *it = aArr [i];
271 }
272
273 /* Arrays of strings */
274
275 static void ToSafeArray (const QValueVector <QString> &aVec,
276 com::SafeArray <BSTR> &aArr);
277 static void FromSafeArray (const com::SafeArray <BSTR> &aArr,
278 QValueVector <QString> &aVec);
279
280 /* Arrays of GUID */
281
282 static void ToSafeArray (const QValueVector <QUuid> &aVec,
283 com::SafeGUIDArray &aArr);
284 static void FromSafeArray (const com::SafeGUIDArray &aArr,
285 QValueVector <QUuid> &aVec);
286
287 /* Arrays of enums. Does a cast similar to what ENUMOut does. */
288
289 template <typename QE, typename CE>
290 static void ToSafeArray (const QValueVector <QE> &aVec,
291 com::SafeIfaceArray <CE> &aArr)
292 {
293 aArr.reset (static_cast <int> (aVec.size()));
294 for (int i = 0; i < aVec.size(); ++i)
295 aArr [i] = static_cast <CE> (aVec.at (i));
296 }
297
298 template <typename CE, typename QE>
299 static void FromSafeArray (const com::SafeIfaceArray <CE> &aArr,
300 QValueVector <QE> &aVec)
301 {
302 aVec.resize (static_cast <int> (aArr.size()));
303 for (int i = 0; i < aVec.size(); ++i)
304 aVec [i] = static_cast <QE> (aArr [i]);
305 }
306
307 /* Arrays of interface pointers. Note: we need a separate pair of names
308 * only because the MSVC8 template matching algorithm is poor and tries to
309 * instantiate a com::SafeIfaceArray <BSTR> (!!!) template otherwise for
310 * *no* reason and fails. Note that it's also not possible to choose the
311 * correct function by specifying template arguments explicitly because then
312 * it starts to try to instantiate the com::SafeArray <I> template for
313 * *no* reason again and fails too. Definitely, broken. Works in GCC like a
314 * charm. */
315
316 template <class CI, class I>
317 static void ToSafeIfaceArray (const QValueVector <CI> &aVec,
318 com::SafeIfaceArray <I> &aArr)
319 {
320 aArr.reset (aVec.size());
321 size_t i = 0;
322 for (typename QValueVector <CI>::const_iterator it = aVec.begin();
323 it != aVec.end(); ++ it, ++ i)
324 {
325 aArr [i] = (*it).raw();
326 if (aArr [i])
327 aArr [i]->AddRef();
328 }
329 }
330
331 template <class I, class CI>
332 static void FromSafeIfaceArray (const com::SafeIfaceArray <I> &aArr,
333 QValueVector <CI> &aVec)
334 {
335 aVec = QValueVector <CI> (aArr.size());
336 size_t i = 0;
337 for (typename QValueVector <CI>::iterator it = aVec.begin();
338 it != aVec.end(); ++ it, ++ i)
339 (*it).attach (aArr [i]);
340 }
341
342protected:
343
344 /* no arbitrary instance creations */
345 COMBase() : mRC (S_OK) {};
346
347#if defined (VBOX_WITH_XPCOM)
348 static XPCOMEventQSocketListener *sSocketListener;
349#endif
350
351 /** Adapter to pass QString as input BSTR params */
352 class BSTRIn
353 {
354 public:
355
356 BSTRIn (const QString &s) : bstr (SysAllocString ((const OLECHAR *) s.ucs2())) {}
357
358 ~BSTRIn()
359 {
360 if (bstr)
361 SysFreeString (bstr);
362 }
363
364 operator BSTR() const { return bstr; }
365
366 private:
367
368 BSTR bstr;
369 };
370
371 /** Adapter to pass QString as output BSTR params */
372 class BSTROut
373 {
374 public:
375
376 BSTROut (QString &s) : str (s), bstr (0) {}
377
378 ~BSTROut()
379 {
380 if (bstr) {
381 str = QString::fromUcs2 (bstr);
382 SysFreeString (bstr);
383 }
384 }
385
386 operator BSTR *() { return &bstr; }
387
388 private:
389
390 QString &str;
391 BSTR bstr;
392 };
393
394 /**
395 * Adapter to pass K* enums as output COM enum params (*_T).
396 *
397 * @param QE K* enum.
398 * @param CE COM enum.
399 */
400 template <typename QE, typename CE>
401 class ENUMOut
402 {
403 public:
404
405 ENUMOut (QE &e) : qe (e), ce ((CE) 0) {}
406 ~ENUMOut() { qe = (QE) ce; }
407 operator CE *() { return &ce; }
408
409 private:
410
411 QE &qe;
412 CE ce;
413 };
414
415#if !defined (VBOX_WITH_XPCOM)
416
417 /** Adapter to pass QUuid as input GUID params */
418 static GUID GUIDIn (const QUuid &uuid) { return uuid; }
419
420 /** Adapter to pass QUuid as output GUID params */
421 class GUIDOut
422 {
423 public:
424
425 GUIDOut (QUuid &id) : uuid (id)
426 {
427 ::memset (&guid, 0, sizeof (GUID));
428 }
429
430 ~GUIDOut()
431 {
432 uuid = QUuid (
433 guid.Data1, guid.Data2, guid.Data3,
434 guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
435 guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
436 }
437
438 operator GUID *() { return &guid; }
439
440 private:
441
442 QUuid &uuid;
443 GUID guid;
444 };
445
446#else /* !defined (VBOX_WITH_XPCOM) */
447
448 /** Adapter to pass QUuid as input GUID params */
449 static const nsID &GUIDIn (const QUuid &uuid)
450 {
451 return *(const nsID *) &uuid;
452 }
453
454 /** Adapter to pass QUuid as output GUID params */
455 class GUIDOut
456 {
457 public:
458
459 GUIDOut (QUuid &id) : uuid (id), nsid (0) {}
460
461 ~GUIDOut()
462 {
463 if (nsid)
464 {
465 uuid = QUuid (
466 nsid->m0, nsid->m1, nsid->m2,
467 nsid->m3[0], nsid->m3[1], nsid->m3[2], nsid->m3[3],
468 nsid->m3[4], nsid->m3[5], nsid->m3[6], nsid->m3[7]);
469 nsMemory::Free (nsid);
470 }
471 }
472
473 operator nsID **() { return &nsid; }
474
475 private:
476
477 QUuid &uuid;
478 nsID *nsid;
479 };
480
481#endif /* !defined (VBOX_WITH_XPCOM) */
482
483 static void addref (IUnknown *aIface) { if (aIface) aIface->AddRef(); }
484 static void release (IUnknown *aIface) { if (aIface) aIface->Release(); }
485
486protected:
487
488 mutable HRESULT mRC;
489
490 friend class COMErrorInfo;
491};
492
493/////////////////////////////////////////////////////////////////////////////
494
495/**
496 * Alternative base class for the CInterface template that adds the errorInfo()
497 * method for providing extended error info about unsuccessful invocation of the
498 * last called interface method.
499 */
500class COMBaseWithEI : public COMBase
501{
502public:
503
504 /**
505 * Returns error info set by the last unsuccessfully invoked interface
506 * method. Returned error info is useful only if CInterface::lastRC()
507 * represents a failure or a warning (i.e. CInterface::isReallyOk() is
508 * false).
509 */
510 const COMErrorInfo &errorInfo() const { return mErrInfo; }
511
512protected:
513
514 /* no arbitrary instance creation */
515 COMBaseWithEI() : COMBase () {};
516
517 void setErrorInfo (const COMErrorInfo &aErrInfo) { mErrInfo = aErrInfo; }
518
519 void fetchErrorInfo (IUnknown *aCallee, const GUID *aCalleeIID) const
520 {
521 mErrInfo.fetchFromCurrentThread (aCallee, aCalleeIID);
522 }
523
524 mutable COMErrorInfo mErrInfo;
525};
526
527/////////////////////////////////////////////////////////////////////////////
528
529/**
530 * Simple class that encapsulates the result code and COMErrorInfo.
531 */
532class COMResult
533{
534public:
535
536 COMResult() : mRC (S_OK) {}
537
538 /**
539 * Queries the current result code from the given component.
540 */
541 explicit COMResult (const COMBase &aComponent)
542 : mRC (aComponent.lastRC()) {}
543
544 /**
545 * Queries the current result code and error info from the given component.
546 */
547 COMResult (const COMBaseWithEI &aComponent)
548 : mRC (aComponent.lastRC())
549 , mErrInfo (aComponent.errorInfo()) {}
550
551 /**
552 * Queries the current result code from the given component.
553 */
554 COMResult &operator= (const COMBase &aComponent)
555 {
556 mRC = aComponent.lastRC();
557 return *this;
558 }
559
560 /**
561 * Queries the current result code and error info from the given component.
562 */
563 COMResult &operator= (const COMBaseWithEI &aComponent)
564 {
565 mRC = aComponent.lastRC();
566 mErrInfo = aComponent.errorInfo();
567 return *this;
568 }
569
570 bool isNull() const { return mErrInfo.isNull(); }
571
572 /**
573 * Returns @c true if the result code repesents success (with or without
574 * warnings).
575 */
576 bool isOk() const { return SUCCEEDED (mRC); }
577
578 /**
579 * Returns @c true if the result code represends success with one or more
580 * warnings.
581 */
582 bool isWarning() const { return SUCCEEDED_WARNING (mRC); }
583
584 /**
585 * Returns @c true if the result code represends success with no warnings.
586 */
587 bool isReallyOk() const { return mRC == S_OK; }
588
589 COMErrorInfo errorInfo() const { return mErrInfo; }
590 HRESULT rc() const { return mRC; }
591
592private:
593
594 HRESULT mRC;
595 COMErrorInfo mErrInfo;
596};
597
598/////////////////////////////////////////////////////////////////////////////
599
600/**
601 * Wrapper template class for all interfaces.
602 *
603 * All interface methods named as they are in the original, i.e. starting
604 * with the capital letter. All utility non-interface methods are named
605 * starting with the small letter. Utility methods should be not normally
606 * called by the end-user client application.
607 *
608 * @param I Interface class (i.e. IUnknown/nsISupports derivant).
609 * @param B Base class, either COMBase (by default) or COMBaseWithEI.
610 */
611template <class I, class B = COMBase>
612class CInterface : public B
613{
614public:
615
616 typedef B Base;
617 typedef I Iface;
618
619 // constructors & destructor
620
621 CInterface() : mIface (NULL) {}
622
623 CInterface (const CInterface &that) : B (that), mIface (that.mIface)
624 {
625 addref (mIface);
626 }
627
628 CInterface (I *aIface) : mIface (aIface) { addref (mIface); }
629
630 virtual ~CInterface() { release (mIface); }
631
632 // utility methods
633
634 void createInstance (const CLSID &aClsId)
635 {
636 AssertMsg (!mIface, ("Instance is already non-NULL\n"));
637 if (!mIface)
638 {
639#if !defined (VBOX_WITH_XPCOM)
640
641 B::mRC = CoCreateInstance (aClsId, NULL, CLSCTX_ALL,
642 _ATL_IIDOF (I), (void **) &mIface);
643
644#else /* !defined (VBOX_WITH_XPCOM) */
645
646 nsCOMPtr <nsIComponentManager> manager;
647 B::mRC = NS_GetComponentManager (getter_AddRefs (manager));
648 if (SUCCEEDED (B::mRC))
649 B::mRC = manager->CreateInstance (aClsId, nsnull, NS_GET_IID (I),
650 (void **) &mIface);
651
652#endif /* !defined (VBOX_WITH_XPCOM) */
653
654 /* fetch error info, but don't assert if it's missing -- many other
655 * reasons can lead to an error (w/o providing error info), not only
656 * the instance initialization code (that should always provide it) */
657 B::fetchErrorInfo (NULL, NULL);
658 }
659 }
660
661 /**
662 * Attaches to the given foreign interface pointer by querying the own
663 * interface on it. The operation may fail.
664 */
665 template <class OI>
666 void attach (OI *aIface)
667 {
668 /* be aware of self assignment */
669 addref (aIface);
670 release (mIface);
671 if (aIface)
672 {
673 mIface = NULL;
674#if !defined (VBOX_WITH_XPCOM)
675 B::mRC = aIface->QueryInterface (_ATL_IIDOF (I), (void **) &mIface);
676#else /* !defined (VBOX_WITH_XPCOM) */
677 B::mRC = aIface->QueryInterface (NS_GET_IID (I), (void **) &mIface);
678#endif /* !defined (VBOX_WITH_XPCOM) */
679 }
680 else
681 {
682 mIface = NULL;
683 B::mRC = S_OK;
684 }
685 };
686
687 /** Specialization of attach() for our own interface I. Never fails. */
688 void attach (I *aIface)
689 {
690 /* be aware of self assignment */
691 addref (aIface);
692 release (mIface);
693 mIface = aIface;
694 B::mRC = S_OK;
695 };
696
697 /** Detaches from the underlying interface pointer. */
698 void detach() { release (mIface); mIface = NULL; }
699
700 /** Returns @c true if not attached to any interface pointer. */
701 bool isNull() const { return mIface == NULL; }
702
703 /**
704 * Returns @c true if the result code repesents success (with or without
705 * warnings).
706 */
707 bool isOk() const { return !isNull() && SUCCEEDED (B::mRC); }
708
709 /**
710 * Returns @c true if the result code represends success with one or more
711 * warnings.
712 */
713 bool isWarning() const { return !isNull() && SUCCEEDED_WARNING (B::mRC); }
714
715 /**
716 * Returns @c true if the result code represends success with no warnings.
717 */
718 bool isReallyOk() const { return !isNull() && B::mRC == S_OK; }
719
720 // utility operators
721
722 CInterface &operator= (const CInterface &that)
723 {
724 attach (that.mIface);
725 B::operator= (that);
726 return *this;
727 }
728
729 CInterface &operator= (I *aIface)
730 {
731 attach (aIface);
732 return *this;
733 }
734
735 /**
736 * Returns the raw interface pointer. Not intended to be used for anything
737 * else but in generated wrappers and for debugging. You've been warned.
738 */
739 I *raw() const { return mIface; }
740
741 bool operator== (const CInterface &that) const { return mIface == that.mIface; }
742 bool operator!= (const CInterface &that) const { return mIface != that.mIface; }
743
744protected:
745
746 mutable I *mIface;
747};
748
749/////////////////////////////////////////////////////////////////////////////
750
751class CUnknown : public CInterface <IUnknown, COMBaseWithEI>
752{
753public:
754
755 typedef CInterface <IUnknown, COMBaseWithEI> Base;
756
757 CUnknown() {}
758
759 /** Creates an instance given another CInterface-based instance. */
760 template <class OI, class OB>
761 explicit CUnknown (const CInterface <OI, OB> &that)
762 {
763 attach (that.mIface);
764 if (SUCCEEDED (mRC))
765 {
766 /* preserve old error info if any */
767 mRC = that.lastRC();
768 setErrorInfo (that.errorInfo());
769 }
770 }
771
772 /** Constructor specialization for IUnknown. */
773 CUnknown (const CUnknown &that) : Base (that) {}
774
775 /** Creates an instance given a foreign interface pointer. */
776 template <class OI>
777 explicit CUnknown (OI *aIface)
778 {
779 attach (aIface);
780 }
781
782 /** Constructor specialization for IUnknown. */
783 explicit CUnknown (IUnknown *aIface) : Base (aIface) {}
784
785 /** Assigns from another CInterface-based instance. */
786 template <class OI, class OB>
787 CUnknown &operator= (const CInterface <OI, OB> &that)
788 {
789 attach (that.mIface);
790 if (SUCCEEDED (mRC))
791 {
792 /* preserve old error info if any */
793 mRC = that.lastRC();
794 setErrorInfo (that.errorInfo());
795 }
796 return *this;
797 }
798
799 /** Assignment specialization for CUnknown. */
800 CUnknown &operator= (const CUnknown &that)
801 {
802 Base::operator= (that);
803 return *this;
804 }
805
806 /** Assigns from a foreign interface pointer. */
807 template <class OI>
808 CUnknown &operator= (OI *aIface)
809 {
810 attach (aIface);
811 return *this;
812 }
813
814 /** Assignment specialization for IUnknown. */
815 CUnknown &operator= (IUnknown *aIface)
816 {
817 Base::operator= (aIface);
818 return *this;
819 }
820
821 /* @internal Used in generated wrappers. Never use directly. */
822 IUnknown *&rawRef() { return mIface; };
823};
824
825/////////////////////////////////////////////////////////////////////////////
826
827/* include the generated header containing concrete wrapper definitions */
828#include "COMWrappers.h"
829
830/** @} */
831
832#endif // __COMDefs_h__
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette