Ich kann mir nicht helfen, dies zu posten, obwohl es keine direkte Antwort auf die Frage ist.
Es gibt einen brillanten MSKB -Artikel aus dem goldenen Alter von COM: Info: Beschreibungen und Arbeitsweise von OLE Threading -Modellen. Immer noch da und hat alle relevanten Informationen. Der Punkt ist, Sie sollten sich keine Sorgen darüber machen, ob es ein Marschall gibt oder nicht, wenn Sie die Regeln befolgen. Registrieren Sie einfach Ihr Objekt als ThreadingModel=Both
, aggregieren Sie den freien Marschall mit CoCreateFreeThreadedMarshaler
, und erledigt sein. COM wird bei Bedarf auf die bestmögliche Weise das Marshaling erledigen. Abhängig vom Apartmentmodell des Kunden kann der Client -Code den direkten Zeiger auf Ihre Schnittstelle empfangen, wenn er auch den Regeln folgt.
Jede "außerirdische" Schnittstelle, die Sie erhalten, wenn eine Methode Ihrer Schnittstelle aufgerufen wird, ist im Rahmen des Anrufs gültig, da Sie im selben Thread bleiben. Wenn Sie es nicht aufbewahren müssen, ist das alles, was zählt.
Wenn Sie jedoch die "Alien" -Kinterfläche zwischenspeichern müssen, wäre der richtige Weg, sie zu speichern CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
:
Um es zu speichern:
- Kritischen Abschnitt eingeben;
- Anruf
CoMarshalInterThreadInterfaceInStream
und speichern die IStream
Zeiger in einem Mitgliedsfeld;
- Kritische Abschnitt verlassen;
Um es abzurufen
- Kritischen Abschnitt eingeben;
- Anruf
CoGetInterfaceAndReleaseStream
Um die Schnittstelle abzurufen
- Anruf
CoMarshalInterThreadInterfaceInStream
und lagern Sie es erneut als IStream
Für jede zukünftige Verwendung
- Kritische Abschnitt verlassen;
- Verwenden Sie die Schnittstelle im Bereich des aktuellen Aufrufs
Um es zu veröffentlichen:
- Wenn Sie es nicht mehr behalten müssen, geben Sie einfach den gespeicherten frei
IStream
(innerhalb des kritischen Abschnitts).
Wenn das "Alien" -Objekt auch frei betrogen ist und die Dinge im selben Prozess geschehen, werden Sie sich wahrscheinlich mit einem direkten Schnittstellenzeiger befassen CoGetInterfaceAndReleaseStream
. Sie sollten jedoch keine Annahmen treffen, und Sie müssen wirklich nicht wissen, ob das Objekt, mit dem Sie sich befassen, das ursprüngliche Objekt oder ein COM -Marshaller -Proxy ist.
Dies kann durch die Verwendung leicht optimiert werden CoMarshalInterface
w/ MSHLFLAGS_TABLESTRONG
/ CoUnmarshalInterface
/ IStream::Seek(0, 0)
/ CoReleaseMarshalData
Anstatt von CoGetInterfaceAndReleaseStream
/CoGetInterfaceAndReleaseStream
, zu unmarshal die gleiche Schnittstelle so oft wie nötig, ohne den Stream freizugeben.
Komplexere (und möglicherweise effizientere) Caching -Szenarien sind möglich, die lokale Speicher des Threads beinhalten. Ich glaube jedoch, dass das ein Überkleid sein würde. Ich habe kein Timing gemacht, aber ich denke, der Overhead von CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
ist wirklich niedrig.
Das heißt, wenn Sie einen Staat beibehalten müssen Speichert Ressourcen oder Objekte, die möglicherweise eine Thread -Affinität erfordern, Anders als oben genannte COM -Schnittstellen, Sie sollte nicht Markieren Sie Ihr Objekt als ThreadingModel=Both
oder aggregieren Sie die FTM.