本地服务器COM中的IConnectionPoint事件

时间:2019-02-11 08:50:12

标签: com

我创建了一个支持ConnectionPoint事件的本地服务器(EXE)COM项目。

idl伪:

interface IAtlClass : IDispatch{
    [id(1)] HRESULT f1();
};
library ComExeLib
{
    dispinterface _IAtlClassEvents
    {
        methods:
            [id(1)] HRESULT f2();
    };
    [
        uuid(...
    ]
    coclass AtlClass
    {
        [default] interface IAtlClass;
        [default, source] dispinterface _IAtlClassEvents;
};

};

服务器内置 32位配置。客户端代码,内置于 64位

HRESULT hr = CoInitialize(NULL);

IAtlClass* atlClass;
hr = CoCreateInstance(CLSID_AtlClass, NULL,
    CLSCTX_LOCAL_SERVER,
    IID_IAtlClass,
    reinterpret_cast<void**>(&atlClass));

hr = atlClass->f1();
IConnectionPointContainer* pICPC = NULL;
hr = atlClass->QueryInterface(IID_IConnectionPointContainer, (VOID **)&pICPC);
IConnectionPoint* pICP = NULL;
hr = pICPC->FindConnectionPoint(DIID__IAtlClassEvents, &pICP);
hr = pICP->Advise((_IAtlClassEvents*)&sink, &cookie);

水槽类:

class Sink : public _IAtlClassEvents
{
public:
    HRESULT STDMETHODCALLTYPE QueryInterface(
        /* [in] */ REFIID riid,
        /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
    {
        if ((DIID__IAtlClassEvents == riid))
        {
            *ppvObject = static_cast<_IAtlClassEvents*>(this);
            AddRef();
            return(S_OK);
        }

        *ppvObject = NULL;
        return(E_NOINTERFACE);
    }

    ULONG STDMETHODCALLTYPE AddRef(void)
    {
        return(InterlockedIncrement(&m_iRef));
    }
    ULONG STDMETHODCALLTYPE Release(void)
    {
        if (0 == InterlockedDecrement(&m_iRef))
        {
            delete this;
            return(0);
        }
        return(m_iRef);
    }
    HRESULT STDMETHODCALLTYPE GetTypeInfoCount()
    HRESULT STDMETHODCALLTYPE GetTypeInfo()
    HRESULT STDMETHODCALLTYPE GetIDsOfNames()
    HRESULT STDMETHODCALLTYPE Invoke()
};

在文件夹ComExe.exe /RegServerregsvr32 ComExePS.dll下用C:\windows\SysWOW\注册服务器,用c:\Windows\System32注册代理。

不确定是否需要,但也尝试在64位以下编译代理存根,但是由于自动生成的ComExe_p.c包含#if !defined(AMD64)..,因此它将无法构建,因此该项目只能以32位构建(似乎仅与this post相关,而我使用的是VS2013。

除最后一个(建议)成功以外的所有客户端代码命令(即使未注册ComExePS.dll,它们也会成功执行)。 Advise使用以下iid调用五次接收器QueryInterface方法(但仅调用它):

{00000003-0000-0000-C000-000000000046}
{ECC8691B-C1DB-4DC0-855E-65F6C551AF49}
{00000003-0000-0000-C000-000000000046}
{0000001B-0000-0000-C000-000000000046}
{IID_IUnknown}

没有一个与IAtlClass相关(某些标准的MS iid是this guy was getting something similar)。

最终Advise返回E_UNEXPECTED Catastrophic failure,问题是我在做什么错?

0 个答案:

没有答案