Re: Is there a way to implement pure IDispatch interfaces in C++?
"raj" <rajayyala@gmail.com> wrote in message
news:1159408189.053227.53800@b28g2000cwb.googlegroups.com
Thanks for the quick response. I guess I failed to get my point across
correctly. When I meant the VB app calls release method, I think they
have an actual "Release()" method on this particular interface( not
the one of IUnknown::Release()). This is what I am confused.
To make it clear: Let's say we have a client VB app VBCli and a COM
object in VB - call it VBSrvr.
Let me see if I understand. You have a COM server implemented in VB.
This server implements a dispinterface that happens to have a method
called Release (quite apart from IUnknown::Release). A, shall we say,
questionable choice for a method name, but you are stuck with it. You
now want to implement the same interface in C++, but the name Release
conflicts with IUnknown::Release.
Here's one way to handle the situation. Suppose your dispinterface looks
like this in IDL:
[object, uuid("1234...")]
dispinterface IA {
methods:
[id(1)] void Release();
[id(2)] void AnotherMethod();
};
Define a new dual interface having the same methods with the same
signatures and, importantly, same DISPIDs, but rename Release to
something else (e.g. Release2, Dispose - doesn't matter):
[object, dual, uuid("4567...")]
interface IB : IDispatch {
[id(1)] HRESULT Release2();
[id(2)] HRESULT AnotherMethod();
};
Implement this dual interface as you normally would, with a slight twist
to interface map:
class CMyClass :
public IDispatchImpl<IB, IID_IB, ...>
{
BEGIN_COM_MAP(CMyClass)
COM_INTERFACE_ENTRY(IB)
COM_INTERFACE_ENTRY(IDispatch)
// This is the punch line:
COM_INTERFACE_ENTRY_IID(DIID_IA, IDispatch)
END_COM_MAP()
STDMETHODIMP Release2();
STDMETHODIMP AnotherMethod();
// Override GetIdsOfNames so that "Release" is treated as an alias
for "Release2"
STDMETHODIMP GetIdsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT
cNames, ...) {
LPOLESTR* names = rgszNames;
if (lstrcmpiW(rgszNames[0], OLESTR("Release")) == 0) {
names = new LPOLESTR[cNames];
names[0] = OLESTR("Release2");
for (int i = 1; i < cNames; ++i) {
names[i] = rgszNames[i];
}
}
HRESULT hr = IDispatchImpl<...>::GetIdsOfNames(riid, names,
cNames, ...);
if (names != rgszNames) delete[] names;
return hr;
}
};
--
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