QueryInterface wird widerwillig über RPC aufgerufen
Frage
In meiner Anwendung erstelle ich ein Objekt A, das über beide ein Objekt B erstellt CreateInstance
.Beide Objekte sollten im selben Prozess leben.
Jetzt sehe ich, dass Objekt B, wenn es nach einer bestimmten Schnittstelle gefragt wird, E_NOINTERFACE zurückgibt, obwohl ich es in der COM_MAP definiert habe:
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()
// .....
};
Und der A-Code:
#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
Wenn ich dies debugge und einen Haltepunkt in COM_MAP einfüge, sehe ich im untersten Frame nicht meinen Quellcode, sondern einige ole32.dlls CRpcThread::WorkerLoop
.
Ich habe keine Ahnung, wie ich das angegeben habe QueryInterface
sollte über OLE und RPC aufgerufen werden.Irgendwelche Ideen?
Lösung
Deiner Beschreibung nach war es das definitiv Marshalling tritt ein.Marshalling erfolgt durch Tunneln von Aufrufen über RPC, daher sieht es ziemlich seltsam aus, aber unter Windows wird es so gemacht.
Der Verbraucherthread wurde wahrscheinlich aufgerufen CoInitializeEx()
mit COINIT_APARTMENTTHREADED
.Da das zu erstellende Objekt markiert war als Free
es konnte nicht in der Wohnung des Anrufers entstanden sein (vgl diese sehr gute Erklärung zum Thema Wohnungen).Stattdessen hat COM versucht, das Marshalling zu aktivieren, was Sie wahrscheinlich nicht getan haben alles, was das Rangieren erleichtert und in solchen Fällen CoCreateInstance()
zurückkehren E_NOINTERFACE
weil COM-Innenleben anfordern eine Reihe von Schnittstellen, die es für das Marshalling verwenden würde und sobald alle diese Anfragen fehlschlagen, endet es mit E_NOINTERFACE
und schickt es zurück, was für Sie natürlich überhaupt nicht bequem ist.
Dann hast du dich verändert Free
Zu Both
was bedeutet "Apartment
von Free
wie COM es für richtig hält“ COM ist es offiziell erlaubt, das Objekt in derselben Wohnung wie der Anrufer abzulegen, und es ist kein Marshalling erforderlich, sodass Sie diesen seltsam aussehenden Fehlercode nicht mehr sehen.
Andere Tipps
Das Thread-Modell für die B
Die Klasse war „Frei“, während ich das Objekt aus einem MultiThreaded-Kontext erstellt habe.Wechseln B
auf „Beide“ wurde das Problem gelöst.