VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h@ 43138

Last change on this file since 43138 was 41689, checked in by vboxsync, 12 years ago

FE/Qt: VBoxDefs renamed to UIDefs and reworked into namespace. Corresponding files which were using VBoxDefs updated.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use