Jump to content

Plugin Entwicklung unerwuenscht?


Findus

Recommended Posts

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

Link to comment

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 by SnoopyDog
Link to comment

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.

Link to comment

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.

Link to comment

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?

Link to comment

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

Link to comment
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).

Link to comment

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

Link to comment

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...

Link to comment

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 :)

Link to comment

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 :)

Link to comment

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 by klausb
Link to comment

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. :bye:

Link to comment
Meinst Du die Verwendung von CoCreateInstance(...) oder

Ich gebe zu Directshow war ein schlechtes beispiel in der beziehung. :bye:

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. :bounce:

 

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...

Link to comment

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 by klausb
Link to comment

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.

Link to comment

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.

Link to comment

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 by klausb
Link to comment

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 by klausb
Link to comment
  • 1 year later...
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

Link to comment
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 by Portisch
Link to comment

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

Link to comment

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

Link to comment

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 by SnoopyDog
Link to comment

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

Link to comment

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...

Link to comment

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

Link to comment
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

Link to comment
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.

Link to comment

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

Link to comment
  • 3 weeks later...

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 by LonelyPixel
Link to comment

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. B)

 

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. :bye:

Link to comment
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.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...