COM Event Interface - wie erweitern?



  • Ich habe eine COM Klasse die bereits verschiedene IDispatch Event Interfaces anbietet.
    Nun müsste ich eines dieser Interfaces um eine zusätzliche Funktion erweitern.

    Die Frage ist: wie macht man das "richtig"?

    Ich hätte versucht einfach ein 2. Interface zu definieren, welches das erste erweitert (also das erste "erbt"), und dann beide als Source Interfaces anzugeben. Das Programm ist mit attributed COM gemacht, dort sieht das dann so aus:

    [
        dispinterface,
        export,
        library_block,
    ...
    ]
    __interface DMyComClassXEvents : IDispatch
    {
        [id(122), helpstring("lala")]
        HRESULT Something([in] LONG x);
    };
    
    [
        dispinterface,
        export,
        library_block,
    ...
    ]
    __interface DMyComClassXEvents2 : DMyComClassXEvents
    {
        [id(123), helpstring("lala")]
        HRESULT SomethingElse([in] LONG x);
    };
    
    [
    ...
    ]
    class MyComClass
    {
    public:
    	__event __interface DMyComClassXEvents; // das alte event interface
    	__event __interface DMyComClassYEvents; // ein ganz anderes event interface
    	__event __interface DMyComClassZEvents; // noch ein anderes event interface
    	__event __interface DMyComClassXEvents2; // das neue event interface
    
        // ...
    };
    

    Funktioniert bloss leider nicht 😞
    Wenn ich es so mache kann ich zwar den COM Server compilieren, allerdings bekommen Clients die sich auf DMyComClassXEvents2 connecten die Methoden von DMyComClassXEvents-ohne-2 nicht mit (z.B. "Something" in diesem Beispiel).
    Wenn sich der Client auf DMyComClassXEvents connected funktioniert "Something", aber "SomethingElse" nicht.
    Wenn ich die Zeile für das alte Interface rausnehme (__event __interface DMyComClassXEvents), dann kann ich den COM Server nichtmehr compilieren, da der generierte Code dann keine "Event ausschicken Funktion" für Something() mehr enthält.

    Ich vermute dass es einfach "nicht ok" ist es so zu machen, also ein Event Interface vom anderen abzuleiten, bloss finde ich dazu keine Informationen im Netz.

    Daher die Frage "wie macht man das"? Muss ja schliesslich eine "kanonische" Lösung für das Problem "ich brauche einen neuen COM Event" geben.

    Eine Möglichkeit (A) wäre natürlich das alte Interface einfach zu erweitern, nur will ich das irgendwie nicht, ist ja ziemlich Pfui. Alte Clients würden sich u.U. auch schön wundern wenn sie auf einmal eine völlig unbekannte DispatchId vor den Latz geknallt bekommen. Die Type-Library Informationen zum alten Interface würden sich auch ändern, auch nicht OK normalerweise.

    Eine andere Möglichkeit (B) wäre ein neues Event Interface zu machen welches nur die neue Event-Methode enthält. Clients die alle Events brauchen müssten sich dann auf beide Event Interfaces connecten. Ginge zwar, finde ich aber irgendwie hässlich.

    Und die dritte Möglichkeit die mir einfällt (C) wäre ein neues Event Interface zu definieren welches einfach "duplikate" der alten Methoden enthält. Quasi so ähnlich wie es bei DWebBrowserEvents und DWebBrowserEvents2 gemacht wurde (nur dass in meinem Fall keine Methoden wegfallen würden). Hier stellt sich noch die Frage ob ich in diesem neuen Interface die Dispatch IDs der alten Methoden wiederverwenden soll (wie es DWebBrowserEvents2 macht), oder neue vergeben. Was ich auf keinen Fall will ist dass es Clientseitig irgendwelche Probleme gibt. Mit neuen IDs dürfte das IMO nicht passieren - was mit "wiederverwendeten" IDs passiert ... kann ich nicht wirklich einschätzen.
    Vor allem da das alte Event Interface ja parallel weiter unterstützt werden muss, das dann die selben IDs verwenden würde.

    Im Moment ist das (C) die Version die ich für die Beste halte, allerding bin ich mir was die Dispatch IDs angeht so garnicht nicht sicher.

    ----

    Das ganze muss auch mit .NET funktionieren, also wenn es da irgendwelche Bekannten Probleme oder Fallstricke mit dem .NET COM Support gibt wäre das auch gut zu wissen.

    Falls jmd. eine Seite kennt wo auf diese Fragen eingegangen wird, oder es mir hier kurz erklären kann, wäre ich sehr froh.



  • push



  • Goldene regel von COM interfaces dürfen nicht geändert werden. Ob die nutzung gleicher dispids probleme macht müsste man ausprobieren, aber ich glaube das gibt probleme, da die ja für das ganze objekt gelten und nicht interface spezifisch sind, da man ja bei VB/etc. konsumenten das konzept der interfaces nicht kennt.



  • Normale COM Interfaces dürfen nicht geändert werden, für (reine) IDispatch Interfaces (also nicht dual) gilt das aber AFAIK nicht.

    ADO z.B. enumeriert dynamisch stored procedures aus SQL Server Datenbanken als normale Member des Connection Objekts.

    Ich denke aber ich werde wirklich einfach ein neues IDispatch interface machen. Bleibt nun nurnoch die Frage ob neue IDs oder nicht. MS selbst scheint es nicht für nötig zu halten neue IDs zu verwenden, hab ich ja schon geschrieben (siehe z.B. DWebBrowserEvents und DWebBrowserEvents2). Hmmmmm...


Anmelden zum Antworten