Re: Passing interface derived from IDispatch as a parameter
Igor R. <igor.rubinov@gmail.com> wrote:
Well, usually the sinks are implemented by our clients, who use our
COM-based SDK, but I believe we can supply some auxiliary classes -
like a base class that they would inherit for their sinks. Currently
the sinks look like this:
class ATL_NO_VTABLE CServerSink :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CServerSink, &CLSID_ServerSink>,
public IDispatchImpl<IServerSink, &IID_IServerSink, &LIBID_SinkLib,
1, 0>,
public IDispEventImpl<1, CServerSink, & __uuidof
(SDKLib::_IServerEvents), &__uuidof(SDKLib::__SDKLib), 1, 0>
{
public:
DECLARE_REGISTRY_RESOURCEID(IDR_SERVERSINK)
BEGIN_COM_MAP(CServerSink)
COM_INTERFACE_ENTRY(IServerSink)
COM_INTERFACE_ENTRY_IID(__uuidof(SDKLib::_IServerEvents), IDispatch)
Don't put event sink into your interface map. IDispEventImpl provides =
its own IUnknown implementation separate from that of its derived class =
(in fact, the class derived from IDispEventImpl doesn't need to be a COM =
object in the first place).
END_COM_MAP()
BEGIN_SINK_MAP(CServerSink)
SINK_ENTRY_EX(1, __uuidof(ClientCoreCOMLib::_IServerEvents), 1,
connectResponded)
END_SINK_MAP()
HRESULT __stdcall connectResponded(SDKLib::IServer *sender);
};
As far as I see, the call goes through IDispEventSimpleImpl::Invoke()
--> IDispEventSimpleImpl::InvokeFromFuncInfo() --> DispCallFunc()
Yes, now that I look at the source, I don't see where an automatic QI =
could possibly happen, either. It looks like I was right after all.
I believe automatic QI does happen with IDispatchImpl (which is based on =
ITypeInfo::Invoke), but not with IDispEvent[Simple]Impl.
So IIUC, I have to implement my own IDispEventImpl2, which would parse
the TLB and perform QI for every relevant argument?
That's the easy part. The hard part is building an appropriate stack =
frame for the method call. Unless you are thoroughly familiar with =
assembly language, you'll probably have a real difficult time with that. =
If it were easy, ATL authors would have done it.
You can hand-craft an IDispatch implementation specific to your =
particular sink interface. That would be much easier, though rather =
tedious.
--
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