进程外组件(EXE服务器) 能使用 回调接口的方法吗? 本帖最后由 jxingcn 于 2010-07-16 12:36:11 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 DCOM是支持 回调接口的.它具有COM的一切特性,不知道你的代理存根dll是否注册 可以使用的。1. 注意代理存根2. 回调实例类CSINK,必须要实现两个引用计数的方法 ULONG __stdcall AddRef(void); ULONG __stdcall Release(void); 代理存根已经注册过,其它的接口调用都是成功的,唯独这一个,向组件内部传递接口指针时,出错!你的意思是说,我只有把我的这个EXE服务器配置成DCOM,才能使用这种方法吗? 我是这样实现的,只是简单的返回一个值,STDMETHODIMP CSink::QueryInterface(const struct _GUID &iid,void ** ppv){ *ppv = this; return S_OK;}ULONG __stdcall CSink::AddRef(void){ return 1; } ULONG __stdcall CSink::Release(void){ return 0; } 难道我这样实现不对么? 能否给出正解! 你的进程外组件 不就是DCOM组件吗,概念不要混淆。 如果这样,能否给些,我调用出错的一些提示,我实在不知道为什么会引起这个错误!断点跟踪后,发现:template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw () { if (m_pInterface != NULL) { return m_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)); //此时m_pInterface = NULL } return E_POINTER; } STDMETHODIMP CSink::QueryInterface(const struct _GUID &iid,void ** ppv){ *ppv=NULL; if (IID_IUnknown==iid || IID_ICallBack==iid) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return S_OK; } return ResultFromScode(E_NOINTERFACE);}ULONG __stdcall AddRef(){ return ++m_cRef;} ULONG __stdcall Release(){ if (0!=--m_cRef) return m_cRef; delete this; return 0;}创建好CSink对象后,先AddRef一次。 你看一下原先这篇文章 http://topic.csdn.net/u/20080910/10/fe2da455-09df-4982-97be-7d914663ed2d.html 我这样做了之后,将回调接口指针传递到组件中是成功了。但COM组件当事件发生时,并不执行我指定的回调函数。我在COM组件中断点,在COM组件中执行了回调函数之后,我客户端的回调函数,并没有被执行。 ICallBack 接口应当在com服务器的idl中定义, 客户端这边include “idl编译出来的头文件” 我和你简单的说一下我是怎么使用的吧!客户端程序:1:在stdafx.h头文件中,#import "...\\ExeSrv.tlb" no_namespace2:添加CSink类,从ICallBack派生,在添加类时,提示找不到ICallBack类,但添加完成后,编译项目,会提示无法实现抽象类在ICallBack类中,这说明,编译的时候,ICallBack类已经识别到了。3:实现CSink类继承的纯抽象函数。4:获取IAdvise接口,目的是往组件中添加ICallBack接口指针 //定义全局变量 CSink m_objSink; //创建组件对象,并获得接口指针。 IAdvisePtr spIAdvise; HRESULT hr = spIAdvise.CreateInstance(__uuidof(DcdzLockerSrv)); if (SUCCEED(hr)) { spIAdvise->Advise((ICallBack*)&m_objSink;); }5:我在CSink的CPP文件中,设置断点。 在用了你说的,实现Queryinterface,AddRef,Release方法后,Advise成功调用。 但组件中在执行这个回调方法时,在CSink的Cpp文件中设置的断点并不能进入,而且这个代码也没执行。 这位兄弟,如果你手上有类似调试通过的代码,能不能发给我一份,不然,我只能用连接点这个方法去实现事件通知了,这个问题,困扰我几天了。 我的Exe服务器是在单元套间中运行 我写了一个简单的例子。下载地址:http://d.download.csdn.net/down/2550115/liyinlei 所有需要传递的接口都必须在IDL中定义,否则接口指针无法列集 access vialoation你可以把代码给我,我帮你调试一下[email protected] VC++源码分享 关于menubar高度和左边空隙的问题,希望GUI高手解答 如何将16进制的BYTE转成CSTRING? 数据库连接和打开的问题,在线等,一经解决立即结贴!!!!! 怎么得到CreateFont里的默认字体宽度?(实在没分了,请原谅) 有谁知道如何使用使用INF 2.5格式来安装我们的控件? 请教高手,怎样使程序再次运行时使用上次更改过的变量值,谢谢! vs2008自动退出 求一个OBB的创建算法...急用~各位大神帮帮忙... sendmessage函数如何使用? 一个关于注册热键的奇怪问题。 如何复制“开始”按钮下的各级子菜单
ULONG __stdcall AddRef(void);
ULONG __stdcall Release(void);
代理存根已经注册过,其它的接口调用都是成功的,唯独这一个,向组件内部传递接口指针时,出错!
你的意思是说,我只有把我的这个EXE服务器配置成DCOM,才能使用这种方法吗?
我是这样实现的,只是简单的返回一个值,
STDMETHODIMP CSink::QueryInterface(const struct _GUID &iid,void ** ppv)
{
*ppv = this;
return S_OK;
}ULONG __stdcall CSink::AddRef(void)
{ return 1; } ULONG __stdcall CSink::Release(void)
{ return 0; } 难道我这样实现不对么? 能否给出正解!
如果这样,能否给些,我调用出错的一些提示,我实在不知道为什么会引起这个错误!断点跟踪后,
发现:
template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw ()
{
if (m_pInterface != NULL) {
return m_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p));
//此时m_pInterface = NULL
} return E_POINTER;
}
STDMETHODIMP CSink::QueryInterface(const struct _GUID &iid,void ** ppv)
{
*ppv=NULL; if (IID_IUnknown==iid || IID_ICallBack==iid)
*ppv=this; if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
} return ResultFromScode(E_NOINTERFACE);
}ULONG __stdcall AddRef()
{
return ++m_cRef;
} ULONG __stdcall Release()
{
if (0!=--m_cRef)
return m_cRef; delete this;
return 0;
}创建好CSink对象后,先AddRef一次。
我这样做了之后,将回调接口指针传递到组件中是成功了。但COM组件当事件发生时,并不执行我指定的回调函数。
我在COM组件中断点,在COM组件中执行了回调函数之后,我客户端的回调函数,并没有被执行。
客户端程序:
1:在stdafx.h头文件中,#import "...\\ExeSrv.tlb" no_namespace
2:添加CSink类,从ICallBack派生,在添加类时,提示找不到ICallBack类,但添加完成后,编译项目,会提示无法实现抽象类在ICallBack类中,这说明,编译的时候,ICallBack类已经识别到了。
3:实现CSink类继承的纯抽象函数。
4:获取IAdvise接口,目的是往组件中添加ICallBack接口指针
//定义全局变量
CSink m_objSink;
//创建组件对象,并获得接口指针。
IAdvisePtr spIAdvise;
HRESULT hr = spIAdvise.CreateInstance(__uuidof(DcdzLockerSrv));
if (SUCCEED(hr))
{
spIAdvise->Advise((ICallBack*)&m_objSink;);
}
5:我在CSink的CPP文件中,设置断点。
在用了你说的,实现Queryinterface,AddRef,Release方法后,Advise成功调用。
但组件中在执行这个回调方法时,在CSink的Cpp文件中设置的断点并不能进入,而且这个代码也没执行。
这位兄弟,如果你手上有类似调试通过的代码,能不能发给我一份,不然,我只能用连接点这个方法去实现事件通知了,这个问题,困扰我几天了。
http://d.download.csdn.net/down/2550115/liyinlei
你可以把代码给我,我帮你调试一下
[email protected]