C++ 调用IConnectionPoint::建议导致崩溃
在我的项目中,我编写了一个将在服务(COM服务器)中调用的组件。还有一个进程将获取该组件的接口,并通过连接点注册回调接口。因此,服务可以使用回调接口进行一些反馈 但我发现,当我使用IConnectionPoint::Advise注册回调接口时,会导致崩溃 我手动实现连接点。以下是我的部分代码:C++ 调用IConnectionPoint::建议导致崩溃,c++,com,rpc,C++,Com,Rpc,在我的项目中,我编写了一个将在服务(COM服务器)中调用的组件。还有一个进程将获取该组件的接口,并通过连接点注册回调接口。因此,服务可以使用回调接口进行一些反馈 但我发现,当我使用IConnectionPoint::Advise注册回调接口时,会导致崩溃 我手动实现连接点。以下是我的部分代码: class ATL_NO_VTABLE CUploadManager : public CComObjectRootEx<CComMultiThreadModel>, public CComC
class ATL_NO_VTABLE CUploadManager :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CUploadManager, &CLSID_UploadManager>,
public IUploadManager,
public IConnectionPointContainer,
public IConnectionPoint
...
// IConnectionPointContainer Functions
STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppEnum);
STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP);
// IConnectionPoint Functions
STDMETHODIMP GetConnectionInterface(IID *pIID);
STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer **ppCPC);
STDMETHODIMP Advise(IUnknown *pUnkSink, DWORD *pdwCookie);
STDMETHODIMP Unadvise(DWORD dwCookie);
STDMETHODIMP EnumConnections(IEnumConnections **ppEnum);
接口事件在组件中生成,该组件将用作连接点中的回调。我只是使用这个类来测试连接点,所以实现非常简单
我不知道这次车祸是怎么发生的。
谢谢你的帮助 问题可能在您的
CDataCallback
类中。它的QueryInterface
实现不安全,返回的接口指针不正确
class CDataCallback : public _IEvents
HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppInterface)
{
*ppInterface = this;
return S_OK;
}
如果请求的接口不是\u IEvents
,则必须检查iid
并返回E\u NOINTERFACE
。基本上,您可以在那里设置一个断点,看看在崩溃之前是否有一个调用,并检查参数
您的接收器可能会被查询到其他接口(
IMarhsal
etc),您必须正确指示您没有实现它们,而不是返回不匹配的指针,使用该指针会导致未定义的行为。如果您生成调试版本并在调试器中运行,您可能能够在实际操作中捕获崩溃。问题可能出在CDATA回调中(特别是如果您没有传递其接口指针-您没有崩溃),并且您没有显示如何实现它。我使用调试版本并使用VS2008调试整个过程,但是地址0x3d0070似乎无效,组件cobase.dll不是开源的,所以我不知道如何做更多的调查。我已经在客户端粘贴了接收器代码,但我认为它可能与接收器无关。非常感谢您的帮助!这是根本原因。我在这个问题上迷失了好几天。谢谢大家。
003d0070() <----crash here
combase.dll!76eea3ab()
[Frames below may be incorrect and/or missing, no symbols loaded for combase.dll]
combase.dll!76ee9d00()
rpcrt4.dll!7612a53d()
mfc90ud.dll!CDialog::OnCmdMsg
...
class CDataCallback : public _IEvents
{
public:
CDataCallback() {}
~CDataCallback() {}
HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppInterface)
{
*ppInterface = this;
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef()
{
return 1;
}
ULONG STDMETHODCALLTYPE Release()
{
return 0;
}
HRESULT __stdcall TestFunc()
{
...
return S_OK;
}
};
class CDataCallback : public _IEvents
HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppInterface)
{
*ppInterface = this;
return S_OK;
}