タイプ ライブラリで定義され、コードに実装されたカスタム インターフェイスがあります。独自のプロキシ/スタブを作成していません。私の場合はIGlobalInterfaceTableを使用して、インターフェイス ポインターをメイン スレッド (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;
}