1

私のアプリケーションでは、オブジェクトAを作成します。これは、両方を介してオブジェクトBを作成しますCreateInstance。両方のオブジェクトは同じプロセスに存在する必要があります。

これで、オブジェクトBが特定のインターフェイスを要求されると、COM_MAPで定義したにもかかわらず、E_NOINTERFACEを返していることがわかります。

class B:
{
    // ....
BEGIN_COM_MAP(B)
    COM_INTERFACE_ENTRY(IB)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IXXX) // the interface I'm interested in
END_COM_MAP()
    // .....
};

そしてAコード:

#define FORWARD_ERROR( expr ) { hr=expr; if( !SUCCEEDED( hr ) ) return hr;}
IBPtr b;
FORWARD_ERROR( b.CreateInstance( __uuidof( B ), 0, CLSCTX_INPROC_SERVER ) );

IXXXPtr x;
HRESULT hrIf = b.QueryInterface( __uuidof( IXXX ), x );
// ===> now x is NULL, and hrIf contains E_NOINTERFACE

これをデバッグし、COM_MAPにブレークポイントを設定すると、最下部のフレームにソースコードが表示されませんが、いくつかのole32.dllが表示されCRpcThread::WorkerLoopます。

QueryInterfaceOLEとRPCを介して呼び出す必要があることをどのように示したかわかりません。何か案は?

4

2 に答える 2

1

あなたの説明から、それは間違いなくマーシャリングキックでした. マーシャリングは RPC を介して呼び出しをトンネリングすることによって行われるため、かなり奇妙に見えますが、それが Windows で行われる方法です。

コンシューマ スレッドは、おそらく で呼び出さCoInitializeEx()COINIT_APARTMENTTHREADEDます。Free作成するオブジェクトは、呼び出し元のアパートメントでは作成できなかったとマークされているため (アパートメントに関するこの非常に優れた説明を参照してください)。代わりに、COM はマーシャリングをオンにしようとしましたが、マーシャリングを容易にするものは何もない可能性が高く、そのような場合、COM の内部動作がマーシャリングに使用する一連のインターフェイスを要求し、それらの要求がすべて失敗すると、最終的にそれを返しますCoCreateInstance()。もちろん、あなたにとってはまったく便利ではありません。E_NOINTERFACEE_NOINTERFACE

次に、「COM が適切と判断する」という意味に変更しまし。COMFree公式にオブジェクトを呼び出し元と同じアパートメントに配置することが許可されており、マーシャリングは必要ないため、奇妙なエラー コードは表示されなくなります。BothApartmentFree

于 2011-05-16T11:40:46.217 に答える
1

Bマルチスレッド コンテキストからオブジェクトを作成している間、クラスのスレッド モデルは「フリー」でした。「両方」に切り替えるBと、問題は解決しました。

于 2011-05-16T10:42:33.733 に答える