进行异步调用 - 我必须创建自己的p/s吗?

Making an async COM call -- do I have to create my own P/S?

本文关键字:自己的 创建 异步 调用      更新时间:2023-10-16

我在类型库中定义了一个自定义接口,并在我的代码中实现。我没有创建自己的代理/存根。在我的情况下,我已经成功地将从主线程(STA)的接口指针填充到了背景线程(STA)。

从该背景线程中,我想对UI线程上的对象进行异步调用。我尚未在对象中实现icallFactory。我看到标准代理确实确实实现了ICAllFactory(即,我可以在ICAllFactory的背景线程上成功使用Qi)。但是我的自定义界面的CreateCall因HRESULT 0x80040150失败(无法从注册表中读取密钥)。

我需要创建自己的代理,以明确实现icallFactory以做到这一点?

这是我的idl:

[
    object,
    uuid(92303FE7-A79D-47DD-923F-62062105C00E),
    async_uuid(2880C40C-9965-4544-AE39-DF08056E8CB6),
    nonextensible,
    pointer_default(unique),
    oleautomation
]
interface IFoo: IUnknown
{
    HRESULT Foo([in] long a, [in] long b);
}
[
    uuid(D58B0A31-A2D5-4BFB-8702-3B710320493B)
]
coclass Foo
{
    [default] interface IFoo;
};

这是我的单元测试中的背景线程:

    static DWORD WINAPI threadproc(LPVOID lpParameter)
    {
        // get arguments
        DWORD cookie = *(DWORD*)lpParameter;
        // initialize COM
        Assert::AreEqual(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
        {
            // get global interface table
            IGlobalInterfaceTablePtr globalInterfaceTable;
            Assert::AreEqual(S_OK, globalInterfaceTable.CreateInstance(CLSID_StdGlobalInterfaceTable));
            // get object
            MyLib::IFooPtr object;
            Assert::AreEqual(S_OK, globalInterfaceTable->GetInterfaceFromGlobal(cookie, MyLib::IID_IFoo, (LPVOID*)&object));
            // get async call factory
            ICallFactoryPtr callFactory;
            Assert::AreEqual(S_OK, object->QueryInterface(&callFactory));
            //
            // Everything is fine up until the CreateCall call below,
            // which fails with HRESULT 0x80040150
            //
            // create async call object
            IUnknownPtr callObject;
            Assert::AreEqual(S_OK, callFactory->CreateCall(MyLib::IID_AsyncIFoo, NULL, IID_IUnknown, &callObject));
        }
        // uninitialize COM
        CoUninitialize();
        // success
        return 0;
    }

据我所知,

,通用卫生员不与async com配合使用。您需要构建(中间生成的)代理(尽管IIRC,如果您要构建DLL,则可以合并存根)。

您还需要注册代理DLL(并使用-dregister_proxy_dll define构建它)。异步com需要定义更多的注册表键才能使其正常工作。