Implementieren von COM-IDispatch-ohne ATL
Schreibe ich eine Excel-RTD-server-Implementierung, und ich bin fest auf dem boilerplate für eine Co-Klasse, die implementiert IDispatch
. Ich habe keinen Zugriff auf ATL, aber ich bin mit ActiveQt, obwohl ich bin daran interessiert, wie dies bei raw-C-oder C++ zu. Wie die Umsetzung des IDispatch
Methoden in einen COM-server?
Die Dokumentation ist nur panickingly schrecklich, wie immer. Was ich bisher gelesen:
- Es ist eine bessere Praxis zu delegieren Sie die
IDispatch
- Methode aufruft, um einigeITypeInfo
. Ist das richtig? - Wenn ja, wie bekomme ich ein
ITypeInfo
zu mir selbst? LoadTypeLib() und Familie (gefolgt von der Suche inITypeLib::GetTypeInfo()
)? - Wenn nicht, wie wird er richtig umgesetzt? Links auf gute Qualität der Dokumentation und selbst-enthaltenen Beispiele sind von großem nutzen.
Den LoadTypeLib()
Ansatz geeignet scheint, für eine COM - client zu erreichen, geben Sie Informationen, die für einige Bibliotheken, nicht für einen COM-server versucht, die Introspektion selbst. Bin ich richtig?
- Typischerweise implementieren Sie IDispatch durch die Zahlung von Microsoft, um Ihnen eine Kopie der ATL. Die Dokumentation aus der Zeit um 1999, als die ATL nicht mehr verfügbar war. Nun, ATL, wie Sie es tun. Zeitraum. (Ich habe IDispatch implementiert. Ich würde nicht empfehlen, die Erfahrung, es ist harte Arbeit und eine Menge eingeben.)
- Nun, ich Stimme mit Ihnen überein, dass dies wahrscheinlich die Günstigste Möglichkeit. Diese verdammten troll-Technologien. (Ich habe gelogen: ich habe Zugriff auf ATL, aber nicht in meiner workstation, und ich wollte nur wissen, ob ich bekommen konnte, zusammen, ohne dass es. Aber hey, Sag niemand darüber, ok?)
- Ich fand "Inside COM+ Base Services" sehr hilfreich "zurück, wenn" - es hat ein Kapitel über die automation, welche sich mit der Umsetzung
IDispatch
. - Hey, vielleicht ist Qt hat einen Weg, es zu tun. Was weiß ich über Qt? Nicht viel.
- Genial, thrysoee.dk/InsideCOM+, vielen Dank. Skimming durch die
IDispatch
Teil gibt mir eine Implementierung mitITypeInfo
undLoadTypeLib()
wie ich bereits erwähnt habe. @Ben: ich fürchte, dass Qt nicht viel code, damit umzugehen. - Blick auf Noseratio Antwort unten, es scheint mit ITypeInfo ist nicht so schwer, nachdem alle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn das interface ordnungsgemäß in der IDL definiert und kompiliert werden, der in eine Art Bibliothek, die Umsetzung
IDispatch
über die Typ-Bibliothek istITypeInfo
ist durchaus machbar, da es meist zu delegieren. Der interessante Teil istITypeInfo::Invoke
die sich auf ein korrektes C++-v-Tabelle layout:Ich verwendet habe, ein ähnliches Konzept zu erstellen ein Skript-callable-wrapper für MSHTML-DOM-Objekte zu umgehen scripting-Sicherheit Beschränkungen.
Also, wo bekommt man die ITypeInfo aus? Im wesentlichen bekommen Sie es durch:
ITypeInfo
Implementierung weiß, welche Funktion aufzurufen ist - es kann nicht einfach nur aufrufen des C++ - Funktionen direkt auf Ihre Klasse, weil C++ hat kein Spiegelbild, und weil es die Sprache ist neutral. Deshalb kann es nur delegieren, dieInvoke
Aufruf einer anderen Methode deklariert, die in die Typ-Bibliothek.E_NOTIMPL
dann setzen Sie eins nach dem anderen)RegisterTypeLib
. Wenn es eingebettet ist, als eine Ressource, sollten Sie rufen Sie diese aus IhrerDllRegisterServer
Umsetzung.LoadTypeLib
. Dies gibt Ihnen eineITypeLib
GetTypeInfoOfGuid
.AddRef
.IDualInterface
habe ich nur verwendetIDispatch
statt; 2. In der MSDN-Dokumentation zur Registrierung ist faux und stackoverflow.com/a/285060/259543 gibt den richtigen Weg. Insbesondere, Sie werden brauchenHKCR\Software\CLSID\<CLSID>\Programmable
für Ihre Komponente in z.B. Microsoft Excel. Ich selbst beabsichtigen, schreiben Sie eine richtige Artikel auf, wie dies zu tun.Implementierung von IDispatch kann leicht sein oder schwer. (Vorausgesetzt, dass Sie nicht verwenden können, ATL).
Der einfache Weg ist nicht TypeInfo (return 0 von
GetTypeInfoCount
undE_NOTIMPL
ausGetTypeInfo
. Niemand sollte es nennen.).Dann alles, was Sie haben, zu unterstützen, ist
GetIDsOfNames
undInvoke
. Es ist nur eine große lookup-Tabelle im wesentlichen.Für
GetIDsOfNames
, zurückDISP_E_UNKNOWNNAME
wenncNames != 1
. Sie nicht auf die Unterstützung der Argumentnamen. Dann haben Sie nur lookuprgszNames[0]
in Ihrer Zuordnung von Namen zu ids.Schließlich implementieren Aufrufen. Alles ignorieren außer pDispParams und pVarResult. Verwenden B. VariantChangeType zu zwingen, die Parameter zu den Typen, die Sie erwarten, und pass auf deine Umsetzung. Den Rückgabewert und zurück. Getan.
Die harte Art und Weise zu verwenden, ITypeInfo und all das. Ich habe es nie getan und würde nicht. ATL macht es einfach so verwenden Sie ATL.
Wenn Kommissionierung die harte Weise, zum Glück.
ITypeInfo
schwieriger als die Implementierung von hand? Es schien leichter für mich auf den ersten Blick, obwohl ich dachte, es war unangebracht zu implementieren, das es so ist.Was man tun kann, ist eine Typ-Bibliothek.
Wenn Sie eine haben, das ist eine Sache, die Sie nicht haben, zu tun. Wenn Sie keine haben, dann erstellen Sie eines mithilfe des MIDL-compiler. Das ist ein kostenloses tool, das im Plattform SDK. Natürlich in diesem Fall, wird es bedeuten, dass Sie haben zu schreiben, eine IDL-Datei (die kann eine Menge Arbeit sein, aber Sie müssen nur definieren, was Sie wollen). Abhängig von der Art des COM-Objekts, die Sie sind targeting, eine IDL-Datei möglicherweise bereits im SDK verfügbar. Sobald Sie haben, dass IDL bereit, können Sie es kompilieren und wieder eine TLB-Datei.
Sobald Sie haben, dass der TLB-Datei, können Sie laden es mithilfe der LoadTypeLib Funktion. Sobald Sie eine ITypeLib Referenz, laden Sie die ITypeInfo, die Sie benötigen (es kann mehr als einmal), und im Grunde route IDispatch-Aufrufe (GetIDsOfNames, etc.) in ITypeInfo-Umsetzung verlangt, da Sie sehr ähnlich sind.