COM Schnittstelle in ein Programm einbinden
-
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 exeDie 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
-
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
-
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).aspxHm, 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
-
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
-
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)'
-
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.
-
Bin jetzt schon was weiter.
Es funktioniert, wenn ich no_namespace bei RICHEDIT20.dll hinzufüge:#include "stdafx.h" #include <iostream> //#include <tom.h> //typedef ITextDocument* ITextDocumentPtr; #import "C:\WINDOWS\system32\RICHED20.dll" no_namespace //_COM_SMARTPTR_TYPEDEF(ITextDocument, __uuidof(ITextDocument)); //using tom::ITextDocumentPtr; #import "C:\Programme\microtech\Buero Plus NexT\BpNexT.exe" rename("LoadImage","BPNTLoadImage"),rename("GetVersionEx","BPNTGetVersionEx") int _tmain(int argc, _TCHAR* argv[]) { CLSID idbpnt; HRESULT hr = ::CLSIDFromProgID (L"BpNT.Application", &idbpnt); if(FAILED(hr)) { std::cout << "CLSIDFromProgID failed" << std::endl; std::cin.get(); return -1; } IID IID_IApplication; hr = IIDFromString(L"{C74FB8F1-A6EF-11D2-B95E-004005232B30}",&IID_IApplication); if(FAILED(hr)) { std::cout << "IIDFromString failed" << std::endl; std::cin.get(); return -1; } BpNT::IAutoApplication7* app; CoInitialise(0); hr = CoCreateInstance(idbpnt,NULL,CLSCTX_LOCAL_SERVER,IID_IApplication,(LPVOID*)&app ); if(FAILED(hr)) { std::cout << "CoCreateInstance failed" << std::endl; std::cin.get(); return -1; } std::cin.get(); return 0; }Generell hätte ich es auch gerne etwas einfacher, in der Doku ist das im VB Code immer ein einzeiler:
Set BpApp = CreateObject("BpNT.Application");
Geht das nicht auch so elegant in C++?So, jetzt bin ich dabei, es mit einem Login zu versuchen, allerdings klappt dieser nicht.
IAutoApplication::Init ( _bstr_t ConnectionName, _bstr_t ConnectionKey, _bstr_t UserName, _bstr_t UserPass )
Ist die Methode dafür.
Wie muss ich nun einen String daran korrekt übergeben? L"foo" und "foo" kompilieren zwar, aber da ich kein Login erhalte, frage ich mich ob da auch das ankommt, was ankommen soll.
Was ist also korrekt, um das umzuwandeln?phlox
-
Die Wrapperklassen verfügen über eine Funktion wie CreateInstance.
Du musst Dir schon etwas die Funktionsweise der Wrapper ansehen. Dann wirst Du seen, dass diese realtive einfach zu bedienen sind.Wenn die Wrapper _bstr_t's haben wollen, dann solltest Du die auch als _bstr_t's übergeben!
-
Martin Richter schrieb:
Die Wrapperklassen verfügen über eine Funktion wie CreateInstance.
Du musst Dir schon etwas die Funktionsweise der Wrapper ansehen. Dann wirst Du seen, dass diese realtive einfach zu bedienen sind.Ja, das werde ich mir mal genauer ansehen.
Wenn die Wrapper _bstr_t's haben wollen, dann solltest Du die auch als _bstr_t's übergeben!
Ja, und wo bekomme ich _bstr_t's? bzw. _bstr_t(L"foo") bringt das selbe Ergebnis.
Letzten Endes funktioniert COM nun. Nur das die Anwendung den Login nicht akzeptiert.phlox
-
_bstr_t sind direkter Bestandeil der COM Engine die automatisch mit dem nutzen von #import verfügbar werden.
-
Ja, hab mich da jetzt auch schlau gemacht.
Wie gesagt es funktioniert, abgesehen davon das der Login nicht klappt.
Ich fang aber eine _com_error exception, von daher ist COM wohl nicht daran schuld, auch bekomme ich eine Programmbezogene Fehlermeldung, etwas was COM garnicht kennen kann.phlox