COM Surrogate bzw. LOCAL_SERVER


  • Mod

    Nein!
    REGCLS_SINGLEUSE bedeutet, dass die Factory nach der ersten Benutzung sich deregistriert... 😉

    After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications. Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must always call CoRevokeClassObject when it is finished with an object class.



  • Hrmmm, wenn dem so wäre, dann würde ich doch kein zweites Objekt von der Klasse erzeugen können? Man kann doch eigentlich nur eine Factory pro CLSID registrieren, will meinen, wenn sich jemand dieser ClassFactory besorgt, wird niemand zweites mehr eine Factory für diese Klasse bekommen.
    Aber ich habe ja zwei unterschiedliche Instanzen von IID_Object, also 2 unterschiedliche Objekte, aber beide von der gleichen Klasse (es gibt überhaupt nur eine Klasse auf meinem System, die das besagte IObject implementiert). Also muss ich doch zweimal die CLSID_Object-Factory benutzt haben, die mir das Objekt rausgehauen hat, das ich dann über IUnknown nach IID_Object gefragt habe?


  • Mod

    Das stimmt nicht. Weil keine Factory existiert wird eine zweite Instanz der DLL geladen. Es ist doch dann genauso, als wenn noch nie eine Instanz erzeugt wurde.

    Es werden doch nicht durch COM prophylaktisch alle Factories erzeugt. Das genau ist ja schon der Unterschied zum Factory Pattern.



  • Oh, ich hatte das jetzt so verstanden, dass COM die dll/exe halt on-demand wie in der Registry eingestellt lädt, aber dann diese eine dll das ist, was überall reingemapped wird oder im surrogate oder dem exe-Local-Server-Prozess läuft. Dass sozusagen die Factory immer wiederverwendet wird, es sei denn, das will man unterbinden, dann war's das mit der Klasse. Late-Loading oder wie man das bezeichnen sollte.
    Na gut, dann kann ich wohl von außen nichts weiter tun. Wer weiß, ob die ClassFactory überhaupt damit klar käme, dass man mehrmals CreateInstance aufruft, oder wenn ja, ob dann immer die selbe Instanz für das IObject-Interface rausgeschmissen würde...


  • Mod

    Der sicherste Weg ist es bestimmt. Das Ganze selbst zu wrappen, wie ich es beschrieben habe. Da es sich aber um ein Objekt handelt ist es natürlich dennoch spannend wie dann der Zugriff aus mehreren Interface Zeigern läuft.



  • Ach, die Schnittstelle ist einfach, was das eigentlich Objekt macht, ist auch total trivial. Mir wurde nur explizit untersagt, die dll durch eine reverse-engineered (ich zitiere: "hacked") Eigenentwicklung zu substituieren. Deswegen muss die Software jetzt also mit ein paar VB6-dlls und der COM-dll installiert werden. Synchronisation wird kein großes Problem. Schöne neue Welt! 😃


  • Mod

    Dann hast Du Dir die Antwort gegeben. Bau ein COM Singleton in einem out of process Server, der nichts anderes macht als dieses Objekt in die IROT zu legen.

    Dann können sich theoretisch sogar andere Prozesse dieses Objekt aus der IROT ziehen. Marshalling macht COM für Dich.



  • Das mit dem Singleton war jetzt der Plan, auch wenn ich jetzt noch nicht daran gedacht habe, IRunningObjectTable zu verwenden und mich erstmal über Moniker schlau lesen muss (hatte jetzt eigentlich vor, einen einfachen Wrapper drumzubasteln, andere CLSID, aber unterstützt dann eben auch IObject. Wollte nur noch ein bissl erzählen, statt hier einfach auf stumm zu schalten. Da freut sich meiner Erfahrung nach der Unterstützer mehr 😉


  • Mod

    🙂



  • Martin Richter schrieb:

    Dann hast Du Dir die Antwort gegeben. Bau ein COM Singleton in einem out of process Server, der nichts anderes macht als dieses Objekt in die IROT zu legen.

    Dann können sich theoretisch sogar andere Prozesse dieses Objekt aus der IROT ziehen. Marshalling macht COM für Dich.

    Was ist, wenn das Objekt aus der ROT an den Client zurückgegeben wurde? Wie funktioniert das mit der Referenzzählung, wie wird so die Lebensdauer des Prozesses kontrolliert? So einfach ist das nicht, meine ich jedenfalls momentan noch. Mir scheint, als müsstest Du die Schnittstelle für dieses Vorhaben exakt nachbauen, damit Du entsprechend CoAddRefServerProcess/CoReleaseServerProcess matchen kannst. Die implementierten Methoden delegieren dann einfach nur.

    Ich glaube fast, ich würde da einfach einen Dienst drumrum stricken. Die IClassFactory erstellt das Objekt und ruft in CreateInstance einfach QueryInterface auf. Endet der Dienst, gibt es ein einfaches CoDisconnectObject und gut. Und da der Client scheinbar ohnehin nur CoCreateInstance aufruft, bringt Dir die ROT außer Gefummel auch keine Vorteile.

    Falls ich völlig neben der Spur bin, bitte ich um Aufklärung!



  • ... oder man baut sich ein eigenes Surrogate, ISurrogate zum implementieren ist ja nun auch kein Hexenwerk. 🙂


Anmelden zum Antworten