接前面两个例子:
本例讲述,C#调用com方法后,com在适当时机回调C#方法。
具体为,c# 先加载一个回调,然后调用COM的add方法,COM把add操作执行后,sleep 1秒,然后触发回调,返回执行结果。
打开项目FirstCom
1.打开FistCom.idl,先增加一个回调定义,如下,其中uuid 需要用GUID工具来生成,这段代码必须在IFirstClass定义之前,否则编译可能会报错。
[
object,
uuid(8900006b-5201-41bf-a08d-7d88fafd7fec)
]
interface ICallBack:IUnknown{
[id(1)]HRESULT Complete([in] LONG RetPara);
};
2.增加调用方法,如下,红色为新增部分:AddCallBack为加载一个回调函数,RemoveCallBack为卸载回调函数,AddWithCallBack为测试回调的方法。
[
object,
uuid(645EE65A-27F6-406B-B2E8-7417660FE0E8),
dual,
nonextensible,
pointer_default(unique)
]
interface IFirstClass : IDispatch{
[id(1)] HRESULT Add([in] LONG para1, [in] LONG para2, [out,retval] LONG* result);
[id(2)] HRESULT TestStruct(struct FirstStruct* result);
[id(3)] HRESULT AddCallBack([in]ICallBack* _callBack);
[id(4)] HRESULT RemoveCallBack(void);
[id(5)] HRESULT AddWithCallBack([in] LONG para1,[in] LONG para2,[out,retval] LONG* result);
};
3.设置头文件FirstClass.h,在public方法里加入刚才定义的三个。
public:
STDMETHOD(Add)(LONG para1, LONG para2, LONG* result);
STDMETHOD(TestStruct)(struct FirstStruct* result);
STDMETHOD(AddCallBack)(ICallBack* _callBack);
STDMETHOD(RemoveCallBack)(void);
STDMETHOD(AddWithCallBack)(LONG para1, LONG para2, LONG* result);
然后在私有变量里面,增加callBack变量,便于保存回调函数:
class ATL_NO_VTABLE CFirstClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFirstClass, &CLSID_FirstClass>,
public IDispatchImpl<IFirstClass, &IID_IFirstClass, &LIBID_FirstComLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
private:
ICallBack* p_CallBack;
public:
CFirstClass()
{
}
4.打开源文件FirstClass.Cpp,增加这三个方法的具体实现:
STDMETHODIMP CFirstClass::AddCallBack(ICallBack* _callBack)
{
p_CallBack=_callBack;
p_CallBack->AddRef();
return S_OK;
}
STDMETHODIMP CFirstClass::RemoveCallBack(void)
{
p_CallBack->Release();
p_CallBack=0;
return S_OK;
}
STDMETHODIMP CFirstClass::AddWithCallBack(LONG para1, LONG para2, LONG* result)
{
*result=para1+para2;
Sleep(1000); //1s
p_CallBack->Complete(*result);
return S_OK;
}
5.编译该项目,成功后,打开测试的WPF项目,首先定义一个回调,继承与刚才在Com中定义的接口ICallBack:
public class FirstCallBack : FirstComLib.ICallBack
{
void FirstComLib.ICallBack.Complete(int RetPara)
{
Debug.WriteLine("CallBack" + RetPara);
Debug.WriteLine("CallBack: " + DateTime.Now.ToString());
}
}
然后测试该回调
FirstComLib.FirstClassClass firstClass = new FirstComLib.FirstClassClass();
firstClass.AddCallBack(new FirstCallBack());
Debug.WriteLine("Start: "+DateTime.Now.ToString());
int result = firstClass.AddWithCallBack(100, 200);
Debug.WriteLine("CallbackResult:" + result);
Debug.WriteLine("End: "+DateTime.Now.ToString());
检测输出结果:
Start: 2011/5/17 16:14:38
CallBack300
CallBack: 2011/5/17 16:14:39
CallbackResult:300
End: 2011/5/17 16:14:39
说明在调用开始一秒后,执行了回调操作。
Over~!