VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/include/COMDefs.h@ 9381

Last change on this file since 9381 was 9381, checked in by vboxsync, 17 years ago

FE/Qt4: Remove that unnecessary header file. It pulls in wrong defines like
Q_WS_X11 on the mac.

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

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