Findus Posted November 24, 2008 Share Posted November 24, 2008 Hallo Entwicklerteam, Aus Mangel an Dokumentation haben viele Benutzer mittlerweile viele Fragen hier ins Forum gestellt um herauszufinden, welche verfügbaren Funktionen und Datenstrukturen man von DVBV aus einem Plugin aufrufen/benutzen kann und welche Möglichkeiten man mit C++ diesbezüglich hat. (Ich rede hier nicht von der COM Schnittstelle.) Leider blieben die meisten Fragen unbeantwortet. Auf der anderen Seite gab es Andeutungen von Lars, dass die eine oder andere Funktion für Pluginbenutzung vorgesehen sei. Konkretes wurde nicht mitgeteilt. Mein Elan hier Software beizusteuern ist mittlerweile fast auf Null zurückgegangen, obwohl ich schon ein paar nette Dinge bei mir am Laufen habe. e.g Unterstützung eines TouchScreen Statusdisplay mit LyricsPlugin ... (alles ueber COM). Natürlich weiß ich, dass es eine Menge an Arbeit bedeutet ein Forum zu betreuen. Die Leute aber im Ungewissen zu lassen ist sehr schlecht und demotivierend. Schaut euch einfach mal an was sich im Umfeld MediaPortal Plugin Entwicklung so alles tut. Gibt es bessere Werbung fuer ein Produkt als Tonnen von guten Plugins??? Findus Quote Link to comment
SnoopyDog Posted November 24, 2008 Share Posted November 24, 2008 (edited) Was willst Du denn wissen? Das meiste geht nun mal über die COM Schnittstelle und für den "Rest" (Basisfunktionen der DLL) gibt es eine Hilfe-Datei. Nachtrag: O.K. - hab recht schnell gefunden, worum es geht Edited November 24, 2008 by SnoopyDog Quote Link to comment
klausb Posted November 24, 2008 Share Posted November 24, 2008 Es ist ärgerlich, wenn man versucht sich durchzukämpfen, z.B. durch re-engineering von Pascal-code, und code findet (z.B. uplugin.pas in Hackbarts MyInternet plugin), aber keine Info dazu bekommt. Noch nichtmal "is nicht supportet" oder so. Man stochert zu oft im Dunkeln. Zu viele Fragen bleiben unbeantwortet. Da bekommt man den Frust. Ich brauch nicht unbedingt fertigen C++ code, aber ich sehe die plugin Hilfe und dann Plugin-Beispiele von der Devs. Da kommen Fragen auf, die dann aber offen bleiben (Bedeutung von IOSDWindowManager, IOSDControl). Warum muss man soviel puzzeln? Dabei habe ich grosse Lust das System zu erweitern. Ich kann Findus nur Recht geben. Das Einbeziehen der Community durch Plugins hat grosses Potential, das hier verschenkt wird. klaus. Quote Link to comment
dgdg Posted November 24, 2008 Share Posted November 24, 2008 Ich denke die/der Entwickler der COM-Schnittstelle möchte sich nicht den Einschränkungen einer Dokumentation unterwerfen. Sprich, wenn man etwas einmal dokumentiert hat, kann es man es nicht mehr so einfach nach belieben ändern. Und da der DVBViewer sich ziemlich dynamisch weiterentwickelt, ist er jeglicher Dokumentation immer ein gutes Stück voraus. Dokumentation hemmt die Weiterentwicklung und bindet Ressourcen, die die Weiterentwicklung behindern. Das gilt für die Benutzeroberfläche sicher genauso wie für die Programmierschnittstellen. Bin ich sarkastisch - nöö, würde ich mich nie trauen. Ich hatte auch mal damit begonnen, von VBA aus einige COM-Versuche zu machen. Ich habe auch schon von VBA aus die verschiedensten Programme per VBA angebunden - meistens ziemlich problemlos, wenn das COM-Interface gut dokumentiert ist. Beim DVBViewer habe ich das nach einigen Versuchen ganz schnell gesteckt. Weil es faktisch keine aktuelle Doku gibt. Quote Link to comment
klausb Posted November 24, 2008 Share Posted November 24, 2008 Muss nicht unbedingt perfekte Doku sein. Da halte ich auch es eher agil. Und klar das bindet Resourcen. Und wenn ich keine vollst. Doku habe, dann fragen die Leute halt nach. Ist ja ok. Aber auch das bindet Resourcen. Das ist aber ein sinnvolles Investment. Je mehr mitbauen, desto attraktiver wird es. Was uns zur Eingangsfrage führt: will man, dass viele mitbauen oder doch lieber nicht? Quote Link to comment
Findus Posted November 25, 2008 Author Share Posted November 25, 2008 Bei DVBViewer Development Fragen kann ja nicht mal die Community helfen, da das Wissen in den Köpfen von ein paar Wenigen steckt. Und da sehe ich dass groesste Problem. Wird nicht geantwortet steht man erst mal auf dem Schlauch. Und das es für einen oder zwei Entwickler zuviel ist auf eine Usergemeinde von Hunderten zu reagieren ist doch offensichtlich. Halloooo liebe Entwickler: Eine Community ist dafür da das Gesammtprojekt zu stärken und sich gegenseitig zu helfen und die Entwickler damit zu entlasten. Dafür muss man natürlich auch ein paar Dinge preisgeben und das Wissen zuerst einmal sharen. (Nur mal so zum Nachdenken) Findus Quote Link to comment
Moses Posted November 25, 2008 Share Posted November 25, 2008 Ich hatte auch mal damit begonnen, von VBA aus einige COM-Versuche zu machen. Ich habe auch schon von VBA aus die verschiedensten Programme per VBA angebunden - meistens ziemlich problemlos, wenn das COM-Interface gut dokumentiert ist. Beim DVBViewer habe ich das nach einigen Versuchen ganz schnell gesteckt. Weil es faktisch keine aktuelle Doku gibt. Die externe COM Schnittstelle ist umfassend und vollständig dokumentiert und auch recht aktuell. Wenn dir die Art der Dokumentation als Basic Programmierer nicht weiter hilft (was ich mir durchaus vorstellen kann), dann ist das was anderes, aber da kann dir dann jeder weiterhelfen, der die Dokumentation gelesen hat und sich etwas mit Objektorientierter Programmierung auskennt. Es geht eher um die "geheimen" Funktionen, die Plugins scheinbar verwenden können (im Gegensatz zu externen Programmen, wie VBA Scripts). Quote Link to comment
Findus Posted November 25, 2008 Author Share Posted November 25, 2008 Moses, ja es geht nicht um die COM Schnittstelle, sondern um die geheimen Plugin Funktionen. Umfassend wuerde ich die Beschreibung der COM Schnittstellen nicht nennen, aber man kann mit etwas Experimentierfreude schon klar kommen. Findus Quote Link to comment
Moses Posted November 25, 2008 Share Posted November 25, 2008 Was vermutest du denn für Plugin Funktionen? Quote Link to comment
Lars_MQ Posted November 25, 2008 Share Posted November 25, 2008 Das ganze läuft auf eine simple "geheime" plugin funktion hinaus: function InitPlugin2: IDVBViewerPlugin; stdcall; {export;} Ab dann wird es recht komplex. das gesamte ist interface basierend. Kein IDispatch interfaces sondern wie zum beispiel in der Directshow/directX entwicklung. Kernstück eines jeden Plugins ist die Skin XML. Die definiert, welche elemente sich in einem OSDfenster befinden. Dem Viewer wird nur mitgeteilt 'Erstelle daraus ein Fenster, und ich bin der besitzer' und er baut alle internen strukturen auf. Über die Interfaces, die das Plugin enthalten muss (IDVBViewerPlugin, iOSDPlugin) läuft dann die gesamte interaktion. Sehr schön kann man das sehen hier und hier. uplugininterfaces.pas enthält alle definitionen und hilfsklassen, die man als grundlage für sein eigenes plugin nehmen kann. uplugin.pas zeigt wie man eine eigene klasse aus den basisklassen ableitet. Ausserdem hat man auf alle COM Interfaces über ISystem.Queryinterface zugriff, dieses interface bekommt man vom viewer über das IDVBViewerPlugin Interface geliefert. Allerdings ist das ganze in pascal, aber die Interfaces lassen sich auch nach C übersetzen, da werden keinerlei pascal exklusive elemente genutzt. Im übrigen wird das OSD im Viewer intern genauso nur über diese interfaces angesprochen. Zusammengefasst: das ganze ist sehr, sehr mächtig, aber aufgrund der komplexität mit sicherheit für den gelegenheitsprogrammierer nicht geeignet... Quote Link to comment
Findus Posted November 25, 2008 Author Share Posted November 25, 2008 Hallo Lars, Das ist doch mal ein Startpunkt. Zum Glueck sind wir keine "Gelegenheitsprogrammierer". Ich werde hier auf jeden Fall mal ansetzen mit der Hoffnung, dass die eine oder andere aufkommende Frage dann von dir noch beantwortet wird. Ich bin auch gerne bereit das Gelernte an andere hier im Forum weiterzugeben. Ihr werdet euch bei Erfolg vor Plugins nicht retten koennen. Gruesse Findus Quote Link to comment
Lars_MQ Posted November 25, 2008 Share Posted November 25, 2008 Klar soweit möglich versuche ich jede frage zu beantworten. Um den plugininterface den schrecken zu nehmen: mehr als 80% wird man sehr verwahrscheinlich nicht nutzen. Das meiste wird ja schon intern vom DVBViewer gehandelt. Das wichtigste in IDVBViewerPlugin: function Init: HRESULT; stdcall; function SetApplication(const OSD: ISystem): HRESULT; stdcall; function Terminate: HRESULT; stdcall; Aufrufreihenfolge: 1. SetApplication: Wird beim initialisieren des DVBViewers aufgerufen, gut geeignet für vorbereitende maßnahmen, ini lesen etc. 2. Init: das OSDSubsystem wird initialisiert. Hier müssen alle OSD-Fenster erzeugt werden. Letzter Aufruf. Terminate: Wenn diese funktion aufgerufen wird, müssen ALLE referenzen, die auf Interfaces gehalten werden, freigegeben werden, sonst gibts mit sicherheit lustige fehlermeldung, die man nie im leben zurückverfolgen kann Quote Link to comment
klausb Posted November 25, 2008 Share Posted November 25, 2008 (edited) Danke für die gute Erklärung. Hierzu: ...Ab dann wird es recht komplex. das gesamte ist interface basierend. Kein IDispatch interfaces sondern wie zum beispiel in der Directshow/directX entwicklung. ... Meinst Du die Verwendung von CoCreateInstance(...) oder? Das ist aber bekanntermassen ein COM Funktion. Ich kann gerade keine andere Fkt finden, die aus GUIDs ein Interface baut. DirectX verwendet da specialle Funktionen. übersehe ich da was? Edit: Habe wohl einen Hänger gehabt. Ich werde mal die wichtigen IFs in C++ übersetzen und instantiieren - per Hand. Edited November 25, 2008 by klausb Quote Link to comment
Moses Posted November 25, 2008 Share Posted November 25, 2008 Es wäre schön, wenn einer der C++ Programmierer das, wenn er es soweit am laufen hat, vielleicht mal als Grundgerüst zur Verfügung stellen könnte... dann müssten nicht immer alle das Rad neu erfinden. Quote Link to comment
Lars_MQ Posted November 25, 2008 Share Posted November 25, 2008 Meinst Du die Verwendung von CoCreateInstance(...) oder Ich gebe zu Directshow war ein schlechtes beispiel in der beziehung. Wir schummeln uns um das CoCreate herum, indem das ISystem übergeben wird. Das ist von IUnknown abgeleitet und somit kann man ein Queryinterface nutzen, um an alle relevanten Interfaces (IWindowmanager ist das wichtigste zum registrieren der Fenster) abzufragen. Ansonsten liefern die entsprechenden Funktionen (aka callbacks) das IOSDWindow interface mit. Dort kann man über getcontrol und ähnliches auf die Elemente des Fensters zugreifen. Nachtrag: Übrigens Callbacks: Das HResult ist sehr wichtig, das es richtig gesetzt wird. Wenn man die entsprechende Action/Message etc behandelt hat und nicht will, dass das weiter im vererbungsbaum runter abgearbeitet wird, sollte man tunlichst ein s_OK setzen. Bei allen anderen Ergebnissen werden die default verarbeitungsroutinen aufgerufen. Nächste Sache: Interaktion: erfolgt syncron über onReceive und OnClick. Darüber laufen Tastatur, Remote und Mauseingaben. Also hurtig, keine langwierigen operation. Wenn Ihr etwas asyncron braucht nutzt onmessage und schickt an Eure WindowID eine OSDMessage über das IDVBOSD.newOSDMessage und dann IOSDMessage.send. In so eine OSDMessage kann man nahezu alle stecken Achja nehmt bitte eine MessageID> 0x5000, um keine kollisionen zu erzeugen... Quote Link to comment
klausb Posted November 25, 2008 Share Posted November 25, 2008 (edited) Schon die erste Frage. Ich habe aus dem hier: IDVBViewerPlugin = interface(IUnknown) ['{7888D3B9-B02F-4ABE-924C-929A9F520775}'] function Init: HRESULT; stdcall; function Name: WideString; stdcall; function SetApplication(const OSD: ISystem): HRESULT; stdcall; function Terminate: HRESULT; stdcall; end; das hier gemacht: typedef struct _DVBViewerPlugin { HRESULT (__stdcall *Init)(); char* (__stdcall *Name)(); HRESULT (__stdcall *SetApplication)(void *); HRESULT (__stdcall *Terminate)(); } DVBViewerPlugin; Und dann das hier: DVBViewerPlugin *p; void init() { p = new DVBViewerPlugin(); p->Name = PluginName; p->Init = Init; p->Terminate = Terminate; p->SetApplication = SetApplication; } DVBViewerPlugin* __stdcall InitPlugin2() { init(); return p; } Die vier Funktionen (Init, Name, ...) sind definiert. Leider wird nach der Rückgabe von p keine Funktion innerhalb der Struktur gerufen. Dafür gibt's später einen NULL deref. Den ISystem Pointer in SetApplication habe ich mal als void * vereinfacht. Ich gehe mal davon aus, dass ich mit dem Ding für's erste nix machen muss. Zumindest in diesem Beispiel nicht. Meine Pascal-Kenntnisse sind ziemlich angestaubt. Kann sein, dass ich diese interface Konstruktion falsch interpretiere. Irgendein Tipp? Nachtrag: So seh'n die Funktionen aus, die ich in die Struktur stecke: char* __stdcall PluginName() { return "DVBTouch"; } HRESULT __stdcall Init() { return S_OK; } HRESULT __stdcall Terminate() { return S_OK; } HRESULT __stdcall SetApplication(void * OSD) { return S_OK; } Gruss, klaus. Edited November 25, 2008 by klausb Quote Link to comment
Lars_MQ Posted November 25, 2008 Share Posted November 25, 2008 widestring ist bstr (?) nicht char also ein 2byte pro char string. Leider sind meine C kenntnisse nicht so berühmt von daher kann ich sonst nicht viel dazu sagen. Eins fällt auf: Sämliche IUnknown funktionen Addref, QueryInterface usw sind nicht vorhanden. Bei interfaces sind die datenstrukturen bzw die reihenfolge und exacte grösse extrem wichtig. Darüber werden (zumindest in delphi) die einsprungsadressen usw berechnet. Quote Link to comment
klausb Posted November 26, 2008 Share Posted November 26, 2008 Hast recht. Ich habe erstmal nur auf die I... typen geschaut und später die T... typen gefunden. Momentan sehe ich allerdings Probleme die interface hierarchie auf C++ Klassen abzubilden. Z.B. bei Vererbung ist nicht ersichtlich, wie das Memory-Layout der Objekte aussieht. Am liebsten würde ich das ganze via IDL - TBL in meinen Code ziehen. Hast Du für die plugin interfaces eine IDL Datei? Mein letzter Versuch sah so aus: class TBaseDVBViewerPlugin { private: int _AddRef() { return -1; } int _Release() { return -1; } protected: void *fosd; HRESULT Init() { return S_OK; } LPWSTR Name() { return L"Test"; } HRESULT QueryInterface(REFIID iid, void ** ppvObject) { return S_OK; } HRESULT SetApplication(void *) { return S_OK; } HRESULT Terminate() { return S_OK; } }; Eine Instanz davon liefere ich in InitPlugin2 zurück. Knallt aber auch. Quote Link to comment
Lars_MQ Posted November 26, 2008 Share Posted November 26, 2008 Nein, die habe ich nicht, sonst wäre sie schon längst veröffentlicht. Quote Link to comment
klausb Posted November 26, 2008 Share Posted November 26, 2008 (edited) Jetzt habe ich einen Hänger. Ich vermute memory alignment Probleme zwischen Delphi und C++. Ich habe mal für die Devs meinen plugin angehängt, um rauszufinden, ob es bei dem Aufruf einer der Callbacks passiert oder schon vorher. Ein Crash beim Callback-Aufruf würde für Probleme mit dem Alignment sprechen. D.h. die Methoden in den Types/Classes sind nicht da, wo DVBViewer sie vermutet. Vielleicht kann ja einer von Euch mal kurz den Debugger anwerfen und im DVBV source schauen, wo's knallt. Danke, klaus. Plugin.zip Edited November 26, 2008 by klausb Quote Link to comment
klausb Posted November 28, 2008 Share Posted November 28, 2008 (edited) Hallo Lars, ich bin jetzt aus Verzweiflung mal auf Delphi umgestiegen, damit ich mal einen Plugin mit der InitPlugin2 Funktion am laufen habe. Ich benutze das RAD Studio für Delphi und C++ 2009 Update 1. Dann habe ich als Bsp mal den Sample plugin MyPrograms als Projekt geladen. Alle Sources und DLL ins Plugin Verzeichnis (wg den Breakpoints). Leider kommt er nie am InitPlugin2 vorbei. Nur die Funktion LibTyp wird angesprochen. function LibTyp: PChar; stdcall; begin result := 'Plugin'; end; Das ganz 3 mal und danach DLLEntry mit DLL_PROCESS_DETACH. Das war's. Was läuft den da falsch? Irgendeine Idee? klaus. Edited November 28, 2008 by klausb Quote Link to comment
erwin Posted March 17, 2010 Share Posted March 17, 2010 Das ganze läuft auf eine simple "geheime" plugin funktion hinaus: function InitPlugin2: IDVBViewerPlugin; stdcall; {export;} ... Über die Interfaces, die das Plugin enthalten muss (IDVBViewerPlugin, iOSDPlugin) läuft dann die gesamte interaktion. Ich hab mir die Samples angeschaut. Ich bin allerdings nicht der große Kenner von Delphi. Meine Frage: wie kommt der DVBV an das iOSDPlugin-Interface. IDVBViewerPlugin ist mir klar, ist ja der return von InitPlugin2 welcher vom DVBV aufgerufen wird. Aber iOSDPlugin? Ich seh die ensprechende Stelle in den Samples einfach nicht. In der Vererbungshierarchie von IDVBViewerPlugin ist es auch nicht enthalten. Momentan sehe ich allerdings Probleme die interface hierarchie auf C++ Klassen abzubilden. C++ Programmierer hier die noch an diesem Problem knobeln? Ich könnte eine Lösung anbieten. erwin Quote Link to comment
Portisch Posted March 17, 2010 Share Posted March 17, 2010 (edited) RAD Studio für Delphi und C++ 2009 Update 1 Ab 2009 is es Unicode!, ausserdem gibt es für 2009 schon mehrere Updates. Am besten ist sowieso auf 2010 umzusteigen. Mit der 2009'er hatte ich viele Probleme. Zu Unicode: aus function LibTyp: PChar; stdcall; begin result := 'Plugin'; end; sollte werden: function LibTyp: PAnsiChar; stdcall; begin result := 'Plugin'; end; Ansonsten kommt nur 'P' statt 'Plugin' beim DVBViewer an und das Plugin wird nicht geladen. Einen Delphi2009/2010 Header für Input Plugin kann ich zu Verfügung stellen falls gewünscht/benötigt. Edited March 17, 2010 by Portisch Quote Link to comment
erwin Posted March 17, 2010 Share Posted March 17, 2010 Noch mal zu meiner Frage. Also ich versteh das so: Der DVBV ruft InitPlugin2 und bekommt las return IDVBViewerPlugin. Er hat somit die Möglichkeit Init Name SetApplication(const OSD: ISystem) Terminate Damit allein kann er jedoch nicht allzuviel anfangen. Muss iOSDPlugin vielleicht durch irgendein DVBV-Funktionsaufruf "registriert" werden? erwin Quote Link to comment
erwin Posted March 17, 2010 Share Posted March 17, 2010 Kann es sein, dass es eigentlich z.B. type IDVBViewerOSDPlugin = Interface( IDVBViewerPlugin, iOSDPlugin ); function InitPlugin2: IDVBViewerOSDPlugin; stdcall; {export;} heissen muss? Also die returnte Instanz beide Interfaces implemetiert haben muss? So ist, denke ich, das Sample aufgebaut. erwin Quote Link to comment
SnoopyDog Posted March 17, 2010 Share Posted March 17, 2010 (edited) Also, ich hab mir nur mal kurz den Code von "myPrograms" angeschaut, das hat mir schon als Beispiel gereicht TYPE cmyDVBViewerPlugin = CLASS(TBaseOSDPlugin) PRIVATE OSDWindowManager : IOSDWindowManager; ....... PROTECTED FUNCTION Init : HRESULT; FUNCTION OnDoesRender (CONST Window : IOSDPlgWindow; Layer : INTEGER) : HRESULT; OVERRIDE; STDCALL; //FUNCTION OnInit (CONST Window : IOSDPlgWindow) : HRESULT; OVERRIDE; STDCALL; //FUNCTION OnMessage (CONST Window : IOSDPlgWindow; CONST Msg : IOSDMessage) : HRESULT; OVERRIDE; STDCALL; //FUNCTION OnReceive (CONST Window : IOSDPlgWindow; Command : TOSDCommand): HRESULT; OVERRIDE; STDCALL; FUNCTION OnWindowLoaded (CONST Window : IOSDPlgWindow) : HRESULT; OVERRIDE; STDCALL; FUNCTION Terminate : HRESULT; OVERRIDE; ..... END; FUNCTION cmyDVBViewerPlugin.Init : HRESULT; VAR Something : IUnknown; BEGIN // IF Assigned(fOSD) THEN BEGIN fOSD.QueryInterface(IID_IOSDWindowManager,OSDWindowManager); ..... // Some more init stuff! CAUTION: is called also on OSD Skin changes. .... Result := S_OK; END { THEN } ELSE BEGIN Result := E_FAIL; END; { ELSE } // IF Assigned(fOSD) THEN BEGIN // z.B.: OSDWindowManager.NewWindow(OSD_WIN_CALL_MONITOR,'CallMonitor.xml',Self,-1,'','','','-','','','',0,FALSE,Something); END; { THEN } END; { Init } FUNCTION cmyDVBViewerPlugin.Terminate : HRESULT; BEGIN OSDWindowManager := NIL; fOSD := NIL; END; { Terminate } ...... FUNCTION InitPlugin2 : IDVBViewerPlugin; STDCALL; BEGIN Result := cmyDVBViewerPlugin.Create; END; { InitPlugin2 } So oder ähnlich Edited March 17, 2010 by SnoopyDog Quote Link to comment
erwin Posted March 18, 2010 Share Posted March 18, 2010 Dank Dir. Mein Problem ist dass ich versuche, es unter C++ zum Laufen zu bringen. Dazu muss ich erstmal den Controlfluss verstehen der nirgends (?) dokumentiert ist, ausser eben implizit als Delphi-Source-Sample. Die Delphiquellen kann ich zwar so halbwegs verstehen aber eben nicht alle Details. Es bleibt meine Frage: wie wird die Verbindung DVBV-iOSDPlugin hergestellt. Wenn ich Dein Codeschnipsel richtig interpretiere, insbesondere diese Zeilen, TYPE cmyDVBViewerPlugin = CLASS(TBaseOSDPlugin) ...... FUNCTION InitPlugin2 : IDVBViewerPlugin; STDCALL; BEGIN Result := cmyDVBViewerPlugin.Create; END; { InitPlugin2 } dann lese ich das so. "Die DVBV-iOSDPlugin wird dadurch hergestellt das der InitPlugin2-Return auch das iOSDPlugin-Interface (in Deinem Falle die TBaseOSDPlugin-Ableitung) implementiert hat" Dies entspräche dann: type IDVBViewerOSDPlugin = Interface( IDVBViewerPlugin, iOSDPlugin ); function InitPlugin2: IDVBViewerOSDPlugin; stdcall; {export;} Ist das so? erwin Quote Link to comment
Lars_MQ Posted March 18, 2010 Share Posted March 18, 2010 Für Delphi gibt es schon ein kleines mitgeliefertes Framework, auf dem man die Pluginerstellung aufbauen kann. Es basiert auf Klassen, die bestimmte Interfaces implementieren. Leider weiss ich nicht genau wie das in C++ gehandhabt wird. Es gibt die Klasse "TBaseDVBViewerPlugin" die über das Interface "IDVBViewerPlugin" die grundlegenden Pluginfunktionen zur verfügung stellt. Alle Interfaces sind von IUnknown abgeleitet und stellen die Standardfunktionen _Addref, _Release und Queryinterface zur Verfügung ( http://msdn.microsoft.com/en-us/library/cc839627.aspx ). Von dieser Klasse sind verschiedene Nachfahren abgeleitet, die automatisch das Interface der Grundklasse durch die Vererbung bereitstellen. Der DVBViewer erhält das "IDVBViewerPlugin" Interface vom Plugin und kann über QueryInterface zum Beispiel das "iOSDPlugin" Interface des Plugins holen. Das "iSystem" Interface, das ein Plugin zu Anfang erhält, stellt per QueryInterface zugriff auf das IDVBViewer Interface bereit, das in der COM Doku beschrieben ist (und damit auf sämtliche dazu untergeordnete Interfaces). Ausserdem erlaubt es zugriff auf IHardwareInfo, ISetUpForm, IOSDWindowManager, IRecordOptions, die in uPluginInterfaces definiert sind. Das grösste Problem ist dabei, die ganzen Interfaces in die C(++) Notation zu übertragen... Quote Link to comment
erwin Posted March 18, 2010 Share Posted March 18, 2010 Danke für die ausführliche Erläuterung. Der DVBViewer erhält das "IDVBViewerPlugin" Interface vom Plugin und kann über QueryInterface zum Beispiel das "iOSDPlugin" Interface des Plugins holen. IDVBViewerPlugin.QueryInterface muss also für den Fall iOSDPlugin ausprogrammiert werden, dann hat auch der DVBV die Verbindung zu iOSDPlugin, womit meine Frage beantwortet wäre. Das grösste Problem ist dabei, die ganzen Interfaces in die C(++) Notation zu übertragen... Ist für mich jetzt eher eine Fleissarbeit - Wenn man weiss welche Logik man umzusetzen hat. erwin Quote Link to comment
erwin Posted March 18, 2010 Share Posted March 18, 2010 Für Delphi gibt es schon ein kleines mitgeliefertes Framework, auf dem man die Pluginerstellung aufbauen kann. Wo wird das mitgeliefert, d.h. wo bekomme ich es her. Ich könnte es ja zu C++ portieren. Warum das Rad zweimal erfinden. erwin Quote Link to comment
Lars_MQ Posted March 18, 2010 Share Posted March 18, 2010 http://www.DVBViewer.info/forum/index.php?showtopic=18506 hier ist es zum beispiel drinne. Ich habe die idl Datei des COM Servers sicherheitshalber mit dran gehängt, falls sie benötigt wird. DVBViewer_idl.zip Quote Link to comment
dbraner Posted March 19, 2010 Share Posted March 19, 2010 Wo wird das mitgeliefert, d.h. wo bekomme ich es her. Ich könnte es ja zu C++ portieren. Warum das Rad zweimal erfinden. erwin Hab jetzt nicht den ganzen Thread gelesen. Aber ich mach das so, dass ich mir in Visual Studio C++ automatisch C++ Wrapperklassen für die COM-Schnittstellen generieren lassen. Geht alles automatisch. Im Hintergrund werden IDL- und Include-Files erzeugt. Habe ich aber bisher nur für den Zugriff auf den DVBViewer per COM gemacht. Noch kein Plugin damit erstellt. Prinzipiell kann man statt einem Plugin ja auch ein normales Programm schreiben, das mit dem DVBViewer gestartet wird. Einige Lösungen, die hier unter Plugin laufen, sind solche Programme. z.B. das Programm für die Ansteuerung von VFD/LCD Displays. Quote Link to comment
nuts Posted March 19, 2010 Share Posted March 19, 2010 Dann gehen dir aber sämtliche Möglichkeiten eine eigene OSD-Seite einzubinden verloren. (http://www.DVBViewer.info/forum/index.php?showtopic=37533) Mal sehn was erwin da noch zaubern kann Quote Link to comment
erwin Posted March 23, 2010 Share Posted March 23, 2010 Brauch mal Hilfe von Delphi-Proggern In uplugininterfaces.pas, welches ich nach C++ portieren möchte, finde ich z.B. so was. function TBaseOSDPlugin.OnLoadSettings(const Window : IOSDPlgWindow): HRESULT; begin end; Explizit hat diese Funktion keinen return-Wert, obwohl ein HRESULT geliefert werden muss. In C++ geht sowas gar nicht erst durch den Compiler. Offensichtlich wird hier implizit ein return-Wert generiert. Welcher (=0)? erwin Quote Link to comment
LonelyPixel Posted April 10, 2010 Share Posted April 10, 2010 (edited) Ich hab das jetzt auch einige Male gesehen. Wenn die Delphi-Programmierer schon nicht wissen, was dann passiert, würde ich mal sehr stark vermuten, dass in diesem Fall 0 zurückgegeben wird, was in etwa S_OK entsprechen dürfte. Allerdings kann das Ergebnis genauso gut undefiniert sein, was dann natürlich ein grober Fehler wäre, der vom C-Compiler völlig zu Recht bemängelt wird. Insbesondere mit den HRESULTs ist auf keinen Fall zu spaßen! Ein anderer Wert als S_OK kommt in seiner Bedeutung einem Ausnahmefehler gleich. Sofern man sich für Fehlererkennung interessiert... Ein paar Links: Keine Aussage, kann aber undefiniert sein Es gibt eine Warnung für diesen Fall Eine definitive Aussage zur Sache habe ich im Web nicht gefunden. Am Ende ist das Verhalten von Delphi gar nicht definiert?! Edited April 10, 2010 by LonelyPixel Quote Link to comment
Lars_MQ Posted April 10, 2010 Share Posted April 10, 2010 Delphi kann funktionen aufrufen wie prozeduren. Das heisst der rückgabe wert ist irrelevant. In diesem fall wird der rückgabewert ignoriert, aber der vollständigkeit halber hätte ich ins Framework schreiben müssen : Result := S_OK; Dort wo es relevant ist, steht es auch. Ansonsten gebt ihr bei undefinierten Result ein Return S_OK aus und der compiler ist glücklich. Es ist ja kein Dualinterface IDispatch interface, wo sowas eine Exception auslöst, sondern lightweight COM, wo das zurückgeben eines E_FAILS wie bei einer WINAPI behandelt wird. Man ärgert sich, das was nicht geklappt hat, aber macht weiter. Quote Link to comment
Griga Posted April 10, 2010 Share Posted April 10, 2010 Ein anderer Wert als S_OK kommt in seiner Bedeutung einem Ausnahmefehler gleich. Stimmt nicht. Ein echter (kritischer) Fehler liegt bei HRESULT nur vor, wenn Bit 31 gesetzt ist. Andere Werte ungleich S_OK können bestimmte Zustände signalisieren. Es gibt z.B. S_FALSE = 1 (Beispiel siehe hier), und speziell bei DirectShow weitere dieser Art (siehe hier). Mit anderen Worten: Das Makro SUCCEEDED(HRESULT) gibt nur false zurück, wenn Bit 31 gesetzt ist. Quote Link to comment
LonelyPixel Posted April 10, 2010 Share Posted April 10, 2010 Aha, wieder was gelernt. Aber das kann man doch nun als Antwort ansehen, oder erwin? Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.