COM Schnittstelle in ein Programm einbinden


  • Mod

    Du kannst MFC Objekte relative einfach mit einer Automatisations Schnittstelle freigeben.

    Ich arbeite allerdings nur noch mit der ATL hier und entsprechenden dualen Interfacen. Das passt auch gut zur MFC ist aber in meinen Augen einfacher zu nutzen.

    BTW: Im Kruglinksi findet sich auch Beispiele zur Automatisation.

    Ansonsten:
    http://www.codeproject.com/KB/COM/mfc_autom.aspx
    Ansonsten einiges unter
    http://www.codeproject.com/KB/COM/index.aspx

    Und natürlich
    http://msdn.microsoft.com/en-us/library/482ck6x8(VS.80).aspx
    gleich die ersten beiden Samples.

    Und speziel eben diese
    http://msdn.microsoft.com/en-us/library/bfew3es6(VS.80).aspx
    siehe links im Baum!

    HTH



  • #import eigent sich auch recht gut zur Einbindung von COM Komponenten.

    #import "foo.dll"
    #import "bar.tlb"
    #import "baz.exe"
    

    Guck dir danach einfach die generierten Header-Files an, da findest du dann sämtliche in der Type-Library enthaltenen Interfaces/Structs/Enums etc.


  • Mod

    Sorry! Ich war mal wieder zu schnell. Meine Links bezieen sich alle darauf, die eigene Applikation zu automatisieren.



  • hustbaer schrieb:

    #import eigent sich auch recht gut zur Einbindung von COM Komponenten.

    #import "foo.dll"
    #import "bar.tlb"
    #import "baz.exe"
    

    Guck dir danach einfach die generierten Header-Files an, da findest du dann sämtliche in der Type-Library enthaltenen Interfaces/Structs/Enums etc.

    Welche generierten Headerfiles?
    Muss ich einfach nur die Exe mit import einbinden?

    phlox


  • Mod

    Du musst die datei importieren, die die Typelibrary enthält. Wenn diese extern (Datei mit Endung tlb) vorliegt dann kannst Du diese nehmen.

    Jedes #import Statement erzeugt Header und Wrapper. Das kannst Du jedoch auch über Parametr steuern.



  • Martin Richter schrieb:

    Du musst die datei importieren, die die Typelibrary enthält. Wenn diese extern (Datei mit Endung tlb) vorliegt dann kannst Du diese nehmen.

    Jedes #import Statement erzeugt Header und Wrapper. Das kannst Du jedoch auch über Parametr steuern.

    Ah, also ich mache #import "foo.exe" mache, erzeugt mir das dann die notwendigen Header?
    Muss ich dann nur den Header einbinden? Wie bekomm ich dann das Application Objekt?



  • ne - die exe alleine reicht nicht
    zu der exe muss es noch diese typelibrary geben, diese definiert die schnittstelle zwischen dir und dieser exe



  • Mr Evil schrieb:

    ne - die exe alleine reicht nicht
    zu der exe muss es noch diese typelibrary geben, diese definiert die schnittstelle zwischen dir und dieser exe

    Die ist in der exe enthalten.
    Gibts nen Tool diese zu extrahieren?



  • oeffne die exe in visual studio, da sind dort dann binary files enthalten - diese musst du mit dem richtigen namen extraieren und speichern



  • Hallo,

    phlox81 schrieb:

    Mr Evil schrieb:

    ne - die exe alleine reicht nicht
    zu der exe muss es noch diese typelibrary geben, diese definiert die schnittstelle zwischen dir und dieser exe

    Die ist in der exe enthalten.
    Gibts nen Tool diese zu extrahieren?

    Probiere alle Möglichkeiten, die dir #import bietet (kann mit exe, mit progid usw. umgehen), siehe:

    http://msdn.microsoft.com/en-us/library/8etzzkb6(VS.80).aspx

    MfG,

    Probe-Nutzer


  • Mod

    phlox81 schrieb:

    Ah, also ich mache #import "foo.exe" mache, erzeugt mir das dann die notwendigen Header?
    Muss ich dann nur den Header einbinden? Wie bekomm ich dann das Application Objekt?

    Nein #import heißt: Suche die TLB, baue einen Header/Wrapper und füge die in den zu kompilierenden Code ein.

    Das Objekt wird wie immer mit CreateInstance erzeugt...



  • So habe gerade #import ausgeführt, bekomme jedoch 3 Fehlermeldungen:

    2 mal das Funktionen schon vorhanden sind (LoadImage, VersionInfoEx) und das ich sie mit rename umbennenen soll.
    Das klappt auch, trotzdem die Frage, schaff ich mir durch die Umbenennung keine neuen Probleme?

    Und dann ist da noch ITextDocumentPtr. Dieser wird nicht erkannt. Wo ist der definiert, bzw. welche lib muss ich dafür einbinden?

    phlox


  • Mod

    Das umbenennen findet doch nur für den Wrapper statt.
    Warum benutzt Du nicht ein Raw-Interface? Bist Du auf die Wrapper angewiesen?

    Bzgl. ITextDocumentPtr, hast Du tom.h included?
    http://msdn.microsoft.com/en-us/library/bb774052(VS.85).aspx



  • Martin Richter schrieb:

    Das umbenennen findet doch nur für den Wrapper statt.
    Warum benutzt Du nicht ein Raw-Interface? Bist Du auf die Wrapper angewiesen?

    Hm, ich hab da nicht wirklich viel ahnung von. Wo ist der Unterschied?

    Bzgl. ITextDocumentPtr, hast Du tom.h included?
    http://msdn.microsoft.com/en-us/library/bb774052(VS.85).aspx

    Hm, interessant. ITextDocumentPtr ist nämlich nicht wirklich ein guter Suchbegriff.
    Nur, wie kann ich das jetzt an import weitergeben?

    //
    // Cross-referenced type libraries:
    //
    //  #import "C:\WINDOWS\system32\RICHED20.dll"
    //
    
    #pragma once
    #pragma pack(push, 8)
    
    #include <comdef.h>
    

    Danach kommt dann der importierte Namespace, tom.h wird da also nicht eingebunden.
    Kann ich jetzt import das sagen das es das soll?
    Oder soll ich import nur einmal ausführen, und die Dateien einfach in mein Verzeichnis kopieren?

    ein import "C...RICHED20.dll" vor den Importbefehl hat es auch nicht gebracht.

    phlox


  • Mod

    Mal eine ganz andere Frage: Warum arbeitest Du beim RTF Control überhaupt mit COM? Das geht doch auch nativ...



  • Martin Richter schrieb:

    Mal eine ganz andere Frage: Warum arbeitest Du beim RTF Control überhaupt mit COM? Das geht doch auch nativ...

    nein, nein. Das ist nix mit dem RTF Control. Ich versuche über COM auf Büro Plus Next zuzugreifen.

    phlox


  • Mod

    Hmmm. Aktuell verstehe ich nicht ganz Dein Problem.
    Also #import ist nichts anderes als ein #include nur dass bei #import on the fly die Header erzeugt werden. Wenn dort was fehlt (Klasse, Interface), dann musst Du die entsprechende Include-Datei in der das Symbol drin ist vor dem #import reinpacken.



  • Ja, so tut es aber leider nicht.

    Hier der Code und die Fehlermeldung:

    #include <iostream>
    #include <tom.h>
    #import "C:\Programme\microtech\Buero Plus NexT\BpNexT.exe" rename("LoadImage","BPNTLoadImage"),rename("GetVersionEx","BPNTGetVersionEx")
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	std::cin.get();
    	return 0;
    }
    
    ITextDocumentPtr TextDocument;
    1>c:\projekte\msvs\bpntfieldlist\bpntfieldlist\debug\bpnext.tlh(3538) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'TextDocument'
    //weirere folgen, immer ITextDocumentPtr
    


  • So, habe jetzt mal die Tom.h durchsucht, und da ist ITextDocument drin, aber ITextDocumentPtr wird dort nirgends definiert.
    Ein simples typedef ITextDocument* ITextDocumentPtr ist es aber auch nicht. (löst zwar einiges auf, da der Typ jetzt bekann ist, aber das ist dann offensichtlich nicht das was eigentlich verlangt wird).

    Also wo finde ich ITextDocumentPtr?

    Ich bin etwas weitergekommen.
    Wenn ich #import "C:\WINDOWS\system32\RICHED20.dll" mache findet sich dort ein
    _COM_SMARTPTR_TYPEDEF(ITextDocument, __uuidof(ITextDocument));
    Allerdings ist das alles im namespace tom. ein using namespace tom hilft leider nicht.
    Ein using tom::ITextDocumentPtr löst einiges, aber nicht alles, dann hab ich diese Kompilierungsfehler:

    1>c:\projekte\msvs\bpntfieldlist\bpntfieldlist\debug\bpnext.tli(2707) : error C2665: "_com_ptr_t<_IIID>::_com_ptr_t": Durch keine der 8 Überladungen konnten alle Argumenttypen konvertiert werden.
    1>        with
    1>        [
    1>            _IIID=_com_IIID<tom::ITextDocument,& _GUID_8cc497c0_a1df_11ce_8098_00aa0047be5d>
    1>        ]
    1>        c:\programme\microsoft visual studio 8\vc\include\comip.h(168): kann '_com_ptr_t<_IIID>::_com_ptr_t(tom::ITextDocument *,bool) throw()' sein
    1>        with
    1>        [
    1>            _IIID=_com_IIID<tom::ITextDocument,& _GUID_8cc497c0_a1df_11ce_8098_00aa0047be5d>
    1>        ]
    1>        c:\programme\microsoft visual studio 8\vc\include\comip.h(190): oder "_com_ptr_t<_IIID>::_com_ptr_t(const CLSID &,IUnknown *,DWORD)"
    1>        with
    1>        [
    1>            _IIID=_com_IIID<tom::ITextDocument,& _GUID_8cc497c0_a1df_11ce_8098_00aa0047be5d>
    1>        ]
    1>        c:\programme\microsoft visual studio 8\vc\include\comip.h(203): oder "_com_ptr_t<_IIID>::_com_ptr_t(LPCWSTR,IUnknown *,DWORD)"
    1>        with
    1>        [
    1>            _IIID=_com_IIID<tom::ITextDocument,& _GUID_8cc497c0_a1df_11ce_8098_00aa0047be5d>
    1>        ]
    1>        c:\programme\microsoft visual studio 8\vc\include\comip.h(216): oder "_com_ptr_t<_IIID>::_com_ptr_t(LPCSTR,IUnknown *,DWORD)"
    1>        with
    1>        [
    1>            _IIID=_com_IIID<tom::ITextDocument,& _GUID_8cc497c0_a1df_11ce_8098_00aa0047be5d>
    1>        ]
    1>        bei Anpassung der Argumentliste '(ITextDocument *, bool)'
    

  • Mod

    Das ITextDokument Interface muss vorher korrekt aufgelöst werden. Inkl. IID!
    Mehr wüsste ich nicht dazu zu sagen.

    Versuch es doch mal ganz primitiv mit einem raw interface import ohne wrapper.
    Ist zwar später etwas mühsamer aber sollte gehen.


Anmelden zum Antworten