 |
Author |
Message |
smarchewy

|
Posted: Fri Apr 04 06:54:35 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Hello everyone,
In the book ATL Internals, here is the description for CComVariant. My
questions,
--------------------
COM permits an object to hand out different binary values each time a client
queries it for a specific interface pointer (with the exception of a query
for the IUnknown interface). Therefore, two VARIANTs containing IDispatch
pointers referencing the same object might not compare for equality.
--------------------
1.
I think it means even if the pointer binary values are different, they may
still be pointed to the same object? Right?
I think it happens only in the situation of multiple inheritance, and in
single inheritance, there is no such issue. Right?
2.
I think the above statement describes the following scenario, in multiple
inheritance, suppose we have interface A inherits from IDispose, and
interface B inherits from IDispose, and have inteface C inherits from both A
and B.
The queryInterface for A and B from interface C will return different result.
thanks in advance,
George
Visual Studio292
|
|
|
|
 |
Igor

|
Posted: Fri Apr 04 06:54:35 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
> I think it means even if the pointer binary values are different,
> they may still be pointed to the same object? Right?
Right. The same COM object (as determined by COM identity check) - not
necessarily the same C++ object (but that's an implementation detail
you, as a COM client, shouldn't care about).
> I think it happens only in the situation of multiple inheritance, and
> in single inheritance, there is no such issue. Right?
Inheritance (whether single or multiple) is not the only possible
technique of implementing COM objects. There are many different ways,
some of which may lead to this situation. For example, read about
tear-off interfaces in the same book.
> I think the above statement describes the following scenario, in
> multiple inheritance, suppose we have interface A inherits from
> IDispose, and interface B inherits from IDispose
You probably mean IDispatch, not IDispose.
> and have inteface C
> inherits from both A and B.
There ain't no such thing as multiple inheritance of COM interfaces. An
interface is always derived from exactly one other interface (except
IUnknown which doesn't have a base interface).
However, a COM object can implement both A and B (though this is usually
a bad idea unless special precautions are taken). Then you can do
something like this to end up with two different IDispatch pointers
pointing to the same object:
IUnknown* pObj; // points to the COM object in question
IA* pA;
pObj->QueryInterface(IID_IA, (void**)&pA);
IB* pB;
pObj->QueryInterface(IID_IB, (void**)&pB);
IDispatch* pDispA = pA;
IDispatch* pDispB = pB;
// Two pointers are not equal
assert(pDispA != pDispB);
// ... but refer to the same COM object
assert( CComPtr<IDispatch>(pDispA).IsEqualObject(pDispB) );
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
|
|
|
|
 |
George

|
Posted: Fri Apr 04 07:44:00 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Igor,
> There ain't no such thing as multiple inheritance of COM interfaces. An
> interface is always derived from exactly one other interface (except
> IUnknown which doesn't have a base interface).
Interface is just typedef of struct, there is multiple inheritance of
struct, why there could not be multiple inheritance for interface?
regards,
George
|
|
|
|
 |
Alf

|
Posted: Fri Apr 04 07:53:15 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
* George:
> Thanks Igor,
>
>
>> There ain't no such thing as multiple inheritance of COM interfaces. An
>> interface is always derived from exactly one other interface (except
>> IUnknown which doesn't have a base interface).
>
> Interface is just typedef of struct, there is multiple inheritance of
> struct, why there could not be multiple inheritance for interface?
COM is language- and compiler-independent.
Many languages do not support multiple inheritance.
Different C++ compilers implement multiple inheritance in slightly different ways.
That doesn't mean that a COM class can't use MI internally for its
implementation (it can do anything whatsoever on the inside).
But as far as consumers of the class (client code) are concerned, there is only
single inheritance.
Cheers, & hth.,
- Alf
|
|
|
|
 |
Alf

|
Posted: Fri Apr 04 07:54:55 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
* George:
>
> In the book ATL Internals, here is the description for CComVariant. My
> questions,
>
> --------------------
> COM permits an object to hand out different binary values each time a client
> queries it for a specific interface pointer (with the exception of a query
> for the IUnknown interface). Therefore, two VARIANTs containing IDispatch
> pointers referencing the same object might not compare for equality.
> --------------------
>
> 1.
>
> I think it means even if the pointer binary values are different, they may
> still be pointed to the same object? Right?
Right. To compare you need to obtain IUnknown-pointers. That's the only
interface guaranteeing pointer equality for the same object.
> I think it happens only in the situation of multiple inheritance, and in
> single inheritance, there is no such issue. Right?
Wrong, discussed else-thread.
Cheers, & hth.,
- Alf
|
|
|
|
 |
George

|
Posted: Fri Apr 04 08:10:01 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Alf,
> Right. To compare you need to obtain IUnknown-pointers. That's the only
> interface guaranteeing pointer equality for the same object.
And IDispatch is not guranteed?
regards,
George
|
|
|
|
 |
George

|
Posted: Fri Apr 04 08:13:02 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Alf,
I just want to discuss from end user (COM developer point of view), we can
write code to make an interface to inherits from multiple interfaces, right?
regards,
George
|
|
|
|
 |
Igor

|
Posted: Fri Apr 04 08:21:32 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
> I just want to discuss from end user (COM developer point of view),
> we can write code to make an interface to inherits from multiple
> interfaces, right?
COM defines the exact binary layout of an interface's vtable. This
binary specification doesn't define how multiple inheritance should be
represented.
In your C++ code, you can write a class that derives from two or more
COM interfaces (and often do, for implementation purposes). But this
class itself is not, by definition, a COM interface, since its binary
layout doesn't match the COM specification.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
|
|
|
|
 |
George

|
Posted: Fri Apr 04 08:50:03 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Igor,
> In your C++ code, you can write a class that derives from two or more
> COM interfaces (and often do, for implementation purposes). But this
> class itself is not, by definition, a COM interface, since its binary
> layout doesn't match the COM specification.
Why it is not? Any COM interface inherits from IUnknown, and I think any
derived class/interface from any COM interface should maintain the same
layout -- i.e. the first 3 methods are QueryInterface/AddRef/Release.
(I think the layout you mean the 3 methods?)
regards,
George
|
|
|
|
 |
Alf

|
Posted: Fri Apr 04 09:27:15 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
* George:
> Thanks Alf,
>
>> Right. To compare you need to obtain IUnknown-pointers. That's the only
>> interface guaranteeing pointer equality for the same object.
>
> And IDispatch is not guranteed?
Hello George The Rule Based System.
Please indicate the /first/ word that threw you off track.
Cheers, & hth.,
- Alf
|
|
|
|
 |
George

|
Posted: Fri Apr 04 09:34:01 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Sorry for my bad description before, Alf! :-)
> Please indicate the /first/ word that threw you off track.
What I am confusing is, query for IDispatch does not guaranteeing pointer
equality for the same object?
regards,
George
|
|
|
|
 |
Alf

|
Posted: Fri Apr 04 09:38:34 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
* George:
> Sorry for my bad description before, Alf! :-)
>
>
>> Please indicate the /first/ word that threw you off track.
>
> What I am confusing is, query for IDispatch does not guaranteeing pointer
> equality for the same object?
To compare you need to obtain IUnknown-pointers. That's the only interface
guaranteeing pointer equality for the same object.
Cheers, & hth.,
- Alf
|
|
|
|
 |
George

|
Posted: Fri Apr 04 09:49:02 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Alf,
Your reply is clear. :-)
regards,
George
> * George:
> > Sorry for my bad description before, Alf! :-)
> >
> >
> >> Please indicate the /first/ word that threw you off track.
> >
> > What I am confusing is, query for IDispatch does not guaranteeing pointer
> > equality for the same object?
>
> To compare you need to obtain IUnknown-pointers. That's the only interface
> guaranteeing pointer equality for the same object.
>
>
> Cheers, & hth.,
>
> - Alf
>
>
|
|
|
|
 |
Igor

|
Posted: Fri Apr 04 10:17:13 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
>> In your C++ code, you can write a class that derives from two or more
>> COM interfaces (and often do, for implementation purposes). But this
>> class itself is not, by definition, a COM interface, since its binary
>> layout doesn't match the COM specification.
>
> Why it is not? Any COM interface inherits from IUnknown, and I think
> any derived class/interface from any COM interface should maintain
> the same layout -- i.e. the first 3 methods are
> QueryInterface/AddRef/Release.
So suppose I have these interfaces:
interface IA : IUnknown {
HRESULT MethodA();
};
interface IB : IUnknown {
HRESULT MethodB();
};
interface IC : IA, IB {
HRESULT MethodC();
};
What should IC's vtable look like, in your opinion? List all methods in
the order they should appear. Note that the following should work:
IC* pC = ...; // initialized somehow
IA* pA = pC;
IB* pB = pC;
pA and pB should point to vtables compatible with IA and IB,
correspondingly.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
|
|
|
|
 |
Igor

|
Posted: Fri Apr 04 10:47:11 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Now I'm curious. Alf repeated the exact same sentence twice,
word-for-word identical. The first time you were confused, but the
second time the reply was clear to you. What happened in between that
had such a profound effect on your comprehension ability?
If it is sufficient to simply see the same answer twice to dispel your
confusion, maybe you could just get into a habit of reading every post
twice? The second time round, the reply would be clear to you, and
everybody will be spared the frustration of reading repetitive
follow-ups.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
> Thanks Alf,
>
>
> Your reply is clear. :-)
>
>
> regards,
> George
>
>
>> * George:
>>> Sorry for my bad description before, Alf! :-)
>>>
>>>
>>>> Please indicate the /first/ word that threw you off track.
>>>
>>> What I am confusing is, query for IDispatch does not guaranteeing
>>> pointer equality for the same object?
>>
>> To compare you need to obtain IUnknown-pointers. That's the only
>> interface guaranteeing pointer equality for the same object.
>>
>>
>> Cheers, & hth.,
>>
>> - Alf
|
|
|
|
 |
George

|
Posted: Sun Apr 06 21:28:01 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Igor,
My mis-understanding before. Now I am clear about Alf's point.
regards,
George
|
|
|
|
 |
George

|
Posted: Sun Apr 06 21:50:00 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
Thanks Igor,
> What should IC's vtable look like, in your opinion? List all methods in
> the order they should appear. Note that the following should work:
In MSVC, IC has "two" vtables. They are,
vtable1 for IA
QueryInterface (from IA::IUnknown)
AddRef (from IA::IUnknown)
Release (from IA::IUnknown)
vtable 2 for IB
QueryInterface (from IB::IUnknown)
AddRef (from IB::IUnknown)
Release (from IB::IUnknown)
when we convert IC instance to IA, vtable 1 will be used, and when we
convert IC instance to IB, vtable2 will be used.
All vtables of IC, IB and IA keep the QueryInterface/AddRef/Release as the
1st three methods. Why do you think it violates COM rules?
regards,
George
|
|
|
|
 |
Igor

|
Posted: Sun Apr 06 23:09:24 CDT 2008 |
Top |
Visual Studio C++ >> CComVariant
>> What should IC's vtable look like, in your opinion? List all methods
>> in the order they should appear. Note that the following should work:
>
> In MSVC, IC has "two" vtables. They are,
>
> vtable1 for IA
>
> QueryInterface (from IA::IUnknown)
> AddRef (from IA::IUnknown)
> Release (from IA::IUnknown)
I don't understand. Where's MethodA
> vtable 2 for IB
>
> QueryInterface (from IB::IUnknown)
> AddRef (from IB::IUnknown)
> Release (from IB::IUnknown)
Where's MethodB?
And finally, where does MethodC go?
> when we convert IC instance to IA, vtable 1 will be used, and when we
> convert IC instance to IB, vtable2 will be used.
And if I don't convert, but use pC directly? What does it point to? I
should have access to 6 methods from it (QueryInterface, AddRef,
Release, MethodA, MethodB and MethodC).
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
|
|
|
|
 |
|
|