2017-04-03 3 views
0

Wenn ich eine Methode auf einer COM-Schnittstelle aufrufen, die eine andere Schnittstelle zurückgibt, ist die PunkVal jedes Mal anders.Warum gibt die COM-Schnittstelle unterschiedliche Werte für dieselbe Aufrufmethode zurück?

Aber wenn ich die alten PunkVal verwenden, um diese Schnittstellenmethoden aufzurufen, funktioniert es auch. Es sieht so aus, als würden viele unnötige Objekte (oder wahrscheinlich Zeiger auf Objekte) erzeugt, aber ich brauche irgendwie, um festzustellen, ob die zurückgegebene Schnittstelle eindeutig ist. Alles, was ich weiß, ist, dass ich eine Schnittstelle (PunkVal) zurückgebe, und der Wert ist in jeder Instanz unterschiedlich. Der Wert, auf den dieser Wert zeigt, ist immer derselbe, aber ich denke, weil er auf die vtable oder etwas verweist, scheint das keine zuverlässige Überprüfung zu sein. Das oder sogar scheinbar getrennte Schnittstellen sind alle die gleiche Schnittstelle.

Um klar sein:

someCOMInterface foo(); 

ich auf foo aufrufen rufen und erwarten punkVal someCOMInterface zu sein, die ich auf Abfrage später muss es Methoden aufrufen aufrufen verwenden. Aber jedes Mal, wenn ich den ersten Aufruf aufruft, bekomme ich ein anderes someCOMInterface (das "gleiche" aber "anders" in dem der Wert, der von invoke zurückgegeben wird).

Antwort

1

Dies ist nicht ungewöhnlich. Es obliegt dem Entwickler der COM-Bibliothek, ob die von mehreren Aufrufen an dieselbe Methode zurückgegebenen Schnittstellenzeiger den gleichen Zeiger zurückgeben oder nicht.

Einer der Gründe dafür, dass verschiedene Zeiger zurückgegeben werden können, ist, dass das in einer bestimmten COM-Bibliothek verwendete Kernobjektmodell möglicherweise nicht COM ist. Ich habe zum Beispiel Objektmodelle in C++ geschrieben, die Dinge wie shared_ptr verwenden, die wohl ein besseres Objektmodell für C++ - Clients ergeben. Aber wenn ich mein C++ - Objektmodell für die Interoperabilität offen lege (oder allgemein als DLL offen lege), ist COM oft die bessere Wahl. Da es schwierig sein kann, ein komplexes, hierarchisches Objektmodell synchron mit einer Gruppe von Wrapper-Klassen zu halten, können Wrapper-Objekte nur temporär sein - wenn nötig erstellt und zerstört, wenn Clients sie nicht mehr verwenden.

Unter diesen Umständen muss der Client möglicherweise noch wissen, dass die Objekte "gleich" sind - zwei verschiedene Objekte, die dasselbe innere Objekt umschließen, können als "gleich" betrachtet werden. Um dies festzustellen, definiert Microsoft die Schnittstelle IObjectEquality. Diese Schnittstelle kann durch COM-Wrapper-Klassen implementiert werden, so dass ein Client explizit prüfen kann, ob zwei ungleiche Zeiger konzeptionell "gleiche" Objekte sind. Die Objekte, die Sie verwenden, können diese Schnittstelle implementieren oder nicht. This blog post zeigt ein vollständiges Beispiel zum Bestimmen der Objektgleichheit unter Verwendung dieser Schnittstelle.

Wenn IObjectEquality nicht implementiert ist, ist es für den Entwickler des COM-Objekts bis einige Mittel vorzusehen zur Herstellung einer solchen Bestimmung, in der Regel durch eine Art von Name oder ID oder andere identifizierende Eigenschaft bereitstellt. Zum Beispiel gibt die Eigenschaft Application.Range von Excel verschiedene Zeiger von nachfolgenden Aufrufen mit denselben Argumenten zurück. Um festzustellen, ob zwei Bereiche gleich sind, können Sie die Range.Address-Methode verwenden, um einen "Bezeichner" für diesen Bereich abzurufen, und diese Kennungen dann vergleichen.

Verwandte Themen