CoCreateInstance E_NOINTERFACE obwohl-Schnittstelle gefunden wird
Habe ich eine COM-Klasse CMyCOMServer
Umsetzung IMyInterface
in einer Anwendung, die beide mit der richtigen GUIDs. CMyCOMServer::QueryInterface
wird S_OK zurückgeben (und der cast selbst auf die richtige Art), wenn IUnknown oder IMyInterface beantragt wird, sonst ist es E_NOINTERFACE zurückgegeben.
In einer anderen Anwendung auf dem gleichen PC, ich nenne:
HRESULT hr = ::CoCreateInstance(__uuidof(CMyCOMServer), 0, CLSCTX_SERVER,
__uuidof(IMyInterface ),(void **)&pInterface);
Es E_NOINTERFACE zurückgegeben. Also bin ich davon ausgegangen, ich mache etwas falsch und habe einen Haltepunkt auf CMyCOMServer::QueryInterface
. Ich fand, dass, wenn CoCreateInstance
genannt wird, QueryInterface
ausgelöst wird mehrere Male mit unterschiedlichen Schnittstellen:
- Erste, IUnknown ist beantragt - kein problem
- Dann zahlreiche Schnittstellen wie IMarshall etc. angefordert werden... diese werden nicht unterstützt, so E_NOINTERFACE wird zurückgegeben,
- Schließlich IMyInterface wird gebeten. Ich überprüfen QueryInterface gibt S_OK zurück und legt
(IMyInterface *)this
wie die interface-Zeiger ist, wie erwartet
Also meine Verwirrung ist der Grund, warum der Aufruf von CoCreateInstance " ist, lässt mich ein NULL-Zeiger und return-code von E_NOINTERFACE, wenn der COM-server-app ist eindeutig die Rückgabe der Schnittstelle, die ich verlangen?
EDIT: meine client-app CoInitialize(NULL) beim Start, das macht keinen Unterschied.
Ja, das tun Sie. Zwei separate apps-auf 1 PC. Ich hatte nie mess around mit Marshalling, bevor, obwohl, das ist, warum ich bin verwirrt. Ich habe kaum gehört, bevor und ich habe einen fairen Betrag von COM-Entwicklung.
InformationsquelleAutor Mr. Boy | 2009-11-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Ihr COM-server ausgeführt wird, in einem anderen Prozess oder eine andere Wohnung in demselben Prozess COM muss wissen, wie man Paket-und Parameter übertragen wenn Sie Anrufe tätigen, um Ihre Schnittstelle. Dieser Vorgang wird als "Marshalling".
Wenn Sie definieren eine benutzerdefinierte Schnittstelle, die Sie implementieren müssen Marshalling Sie mithilfe einer der folgenden Methoden.
und stub, die Sie müssen sich registrieren auf dem system. Dies ist wahrscheinlich die beste option, da Sie bereits definiert haben Ihre Schnittstelle.
custom-Schnittstelle und verwenden Sie die
marshaller, die bereits Teil
das COM-framework
Wenn Sie das Debuggen des COM-server, obwohl Sie sehen, dass Sie wieder Ihre benutzerdefinierte Schnittstelle der Aufruf von QueryInterface, macht er es nicht, über den Prozess der Begrenzung, da COM kann nicht herausfinden, wie Marschall, die Schnittstelle, damit der Kunde sieht E_NOINTERFACE.
UPDATE (basierend auf Ihren Kommentar)
Ist dies eine vorhandene COM-server-app, dann haben Sie wahrscheinlich bereits einen proxy/stub. Sie müssen sich registrieren, dies auf dem client und dem server. Könnte es sein, dass Sie testen diese auf einer neuen Maschine(s) und Sie einfach vergessen, Sie zu registrieren? Registrieren Sie sich einfach regsvr32 auf dem proxy - /stub-dll.
Ich denke, das ist die beste Antwort. es stellt sich heraus, wir haben einen proxy-stub-DLL, ich war einfach nicht bewusst zu sein. Mit regsvr32 behoben.
InformationsquelleAutor DSO
Dies geschieht, weil COM-subsystem versucht, Marschall Ihre benutzerdefinierte Schnittstelle (IMyInterface) und hat einfach keine Ahnung, wie das geht. Das passiert, weil entweder der server ist out-proc, oder weil der server in-proc und das Gewinde der consumer-Anwendung, die CoCreateInstance() aufgerufen hat, CoInitialize()/CoInitializeEx() falsch, so dass der "Multi-Threaded apartment" angefordert wird-wie im Artikel erwähnt Benutzer Thomas bezieht sich auf die in der anderen Antwort.
Wenn Sie nur ein in-proc-server, der Sie unterdrücken konnte marshalling, indem sichergestellt wird, dass die thread-aufrufen von CoCreateInstance() entweder CoInitialize() oder CoInitializeEx() mit COINIT_APARTMENTTHREADED durchzusetzen "single-threaded apartment".
Wenn Sie ein out-proc-server-Sie können nicht um das marshalling. Im letzteren Fall könnte man Folgendes tun:
Haben Sie diesen Artikel Lesen?
Ja das hab ich jetzt. sieht es relevant ist, aber nicht mir irgendwelche Ideen was zu verändern. Die server-app läuft schon seit Jahren und ich warf zusammen eine neue client-MFC-Anwendung, mit ihm zu interagieren. Ich din nicht sehen, jede Erwähnung von, wie man 'unterdrücken marshalling" in diesem Artikel.
Der Schlüssel ist, wie die CoInitializeEx()/CoInitialize() aufgerufen wird, durch den AUFTRAGGEBER. Sollte es nennen es "Wohnung" - entweder CoInitialize() oder CoInitializeEx() mit COINIT_APARTMENTTHREADED.
Wenn Sie nicht erzwingen "Wohnung" marshalling wird kick in. Die Einstellung erfolgt saparately für jeden thread des client.
InformationsquelleAutor sharptooth
Könnte dies das threading-Modell problem, dass Raymond Chen schrieb über?
Bearbeiten Sie in der Antwort auf den Kommentar:
Es ist mehr über threading-Modelle als über marshalling, wirklich.
InformationsquelleAutor Thomas
Vorherigen Kommentare über
E_NOINTERFACE
zurückgegeben, da marshalling-Schnittstelle fehlt, war sehr hilfreich,allerdings
für uns ist die Antwort/Lösung Bestand darin, die Kraft die Haupt-Anwendung (der Aufruf
CoCreateInstance
)STA
(single threaded apartment), und dies wurde durch das setzen einer advanced-linker-option, d.h.:oder auf der link-Befehlszeile, die Sie tun:
Dies verhindert, dass eine Mischung von MTA und STA, was bewirkt, dass ein Anruf über threads.
Hoffe jemand anderes findet dies sehr hilfreich.
InformationsquelleAutor Mike Watry