A follow-up to this question, I have the following CerberusNative.idl
file (this is an ATL project written in Visual C++ which exposes a COM object):
[
object,
uuid(AECE8D0C-F902-4311-A374-ED3A0EBB6B49),
nonextensible,
pointer_default(unique)
]
interface ICallbacks : IUnknown
{
[id(1)] HRESULT UserExit([in] int errorCode, [in] BSTR errorMessage);
[id(2)] HRESULT UserAttemptingReconnection();
[id(3)] HRESULT UserReconnected();
};
[
object,
uuid(B98A7D3F-651A-49BE-9744-2B1D8C896E9E),
dual,
nonextensible,
pointer_default(unique)
]
interface ICerberusSession : IDispatch {
...
[id(5)] HRESULT SetCallbacks([in] ICallbacks* callbacks);
};
I am attempting to create an interface for setting up callback methods which route from the COM object back to an implementation of said methods from the caller.
I am trying to run the following code:
HRESULT prolonguedDisconnection(int code, BSTR *message) {
std::wcout << code << ": " << message << std::endl;
}
HRESULT reconnecting() {
std::wcout << "Reconnecting." << std::endl;
}
HRESULT reconnected() {
std::wcout << "Reconnected." << std::endl;
}
...
CoInitialize(NULL);
CerberusNativeLib::ICallbacksPtr callbacks;
callbacks.CreateInstance(__uuidof(CerberusNativeLib::ICallbacks));
callbacks->UserExit = prolonguedDisconnection;
callbacks->UserAttemptingReconnection = reconnecting;
callbacks->UserReconnected = reconnected;
CerberusNativeLib::ICerberusSessionPtr session;
session.CreateInstance(__uuidof(CerberusNativeLib::CerberusSession));
session->SetCallbacks(callbacks);
However, I am not sure how to properly set up the callback methods. Any ideas on how to do this? I get this compiler error on lines such as callbacks->UserExit = prolonguedDisconnection;
:
Error C2659 '=': function as left operand
I needed simply to implement the interface in a separate class:
Then, to use it:
You defined
ICallbacks
as an interface and the object that implementsICerberusSession
accepts aICallbacks
pointer so that it could invoke calls back on certain events. This is a good design and works well. However, it usually assumes that your code (last code snippet at the bottom) instantiates session object viaCreateInstance
as you do, and the other interface with callback methods is implemented on your side.Your code implements a COM object, which in turn implements
ICallbacks
. You create an instance of such COM object (esp. withoutCoCreateInstace
- it's typically client code on your side) and you passICallbacks
interface as an argument inSetCallbacks
call. Note that there is no assignment involved. Session object is expected to do a call, e.g.ICallbacks::UserExit
on supplied pointer and this is how your code receives control through the callback interface - your client side code implementation ofICallbacks
has itsUserExit
method called.