Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调用IConnectionPoint::建议导致崩溃_C++_Com_Rpc - Fatal编程技术网

C++ 调用IConnectionPoint::建议导致崩溃

C++ 调用IConnectionPoint::建议导致崩溃,c++,com,rpc,C++,Com,Rpc,在我的项目中,我编写了一个将在服务(COM服务器)中调用的组件。还有一个进程将获取该组件的接口,并通过连接点注册回调接口。因此,服务可以使用回调接口进行一些反馈 但我发现,当我使用IConnectionPoint::Advise注册回调接口时,会导致崩溃 我手动实现连接点。以下是我的部分代码: class ATL_NO_VTABLE CUploadManager : public CComObjectRootEx<CComMultiThreadModel>, public CComC

在我的项目中,我编写了一个将在服务(COM服务器)中调用的组件。还有一个进程将获取该组件的接口,并通过连接点注册回调接口。因此,服务可以使用回调接口进行一些反馈

但我发现,当我使用IConnectionPoint::Advise注册回调接口时,会导致崩溃

我手动实现连接点。以下是我的部分代码:

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;
}