Re: Can't add property getter for write-only property in derived interface
andrew.molyneux@gmail.com wrote:
On Jun 25, 1:35 pm, "Igor Tandetnik" <itandet...@mvps.org> wrote:
In this case, make sure IDispatch portion of IMyInterface actually
delegates to that of IMyInterface2. Otherwise you will be in a bad
situation where, say, IDispatch::Invoke behaves differently
depending on the way IDispatch pointer was obtained.
Hmmm... either you've misunderstood me, or I've failed to grasp
something quite fundamental and important.
I'm only planning to have a single IDispatch implementation - my
interface and coclass declarations look like this (with some
properties removed for clarity):
[object,dual,pointer_default(unique)]
__interface IMyInterface : IDispatch
{
[propput, id(1)] HRESULT MyProperty([in] VARIANT_BOOL value);
};
[object,dual,pointer_default(unique)]
__interface IMyInterface2 : IDispatch
{
[propput, id(1)] HRESULT MyProperty([in] VARIANT_BOOL value);
[propget, id(1)] HRESULT MyProperty([out, retval] VARIANT_BOOL*
pValue);
};
[coclass, default(IMyInterface2)]
class ATL_NO_VTABLE CMyClass :
public IDispatchImpl<IMyInterface2>,
public IMyInterface
Note that you have two IDispatch vtables in CMyClass - one inherited
from IMyInterface2, and one from IMyInterface. Believe it or not, you
have two distinct implementations of IDispatch::Invoke. One is
IDispatchImpl<IMyInterface2>::Invoke. The other is generated at compile
time by the attribute provider from the definition of IMyInterface. The
two Invoke implementations support different capabilities - one allows
DISPATCH_PROPERTYGET operation on a property with as DISPID of 1, and
the other does not. Depending on the exact sequence of operations that
led to obtaining an IDispatch pointer from your object, the client may
end up calling one or the other Invoke implementation, likely leading to
some unpleasant surprises.
Are you saying this will cause a problem?
Yes.
If so, what exactly do I need to do to fix it?
I'm not familiar with intricacies of attribute-generated code, so it is
difficult for me to guess at a proper fix. In a non-attributed project,
CMyClass declaration above would fail to compile (the compiler would
complain that a few pure virtual functions, such as IDispatch::Invoke,
are left unimplemented). If you were to switch to non-attributed
project, I'd suggest something like this:
class ATL_NO_VTABLE CMyClass :
public IDispatchImpl<IMyInterface2>,
public IMyInterface
{
public:
// Explicitly implement IDispatch methods,
// by delegating to IDispatchImpl<IMyInterface2> implementation
STDMETHODIMP Invoke(DISPID dispid, ...) {
return IDispatchImpl<IMyInterface2>::Invoke(dispid, ...);
}
// Similarly for the other three methods
};
--
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