VirtualBox

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

Last change on this file since 14728 was 13959, checked in by vboxsync, 16 years ago

FE/Qt: Fixed support for safe arrays of enums (affected XPCOM platforms).

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