Entwickler-Ecke
Sonstiges (Delphi) - Interfaces vs. Callback
jackle32 - Mo 25.05.15 15:16
Titel:  Interfaces vs. Callback
Hallo zusammen,
ich bin im Moment in den Tiefen der Dll Programmierung angekommen. Dabei habe ich verschiedene Arten zu programmieren kennen gelernt.
Im Normalfall ist ja eine Dll einbinden eine One-Way Kommunikation von Exe zu Dll.
Ich habe mich jetzt dabei auf die Suche gemacht wie ich den umgekehrten Weg auch gehen kann. Dabei bin ich auf zwei Möglichkeiten gestoßen.
Entweder man implementiert ein Interface oder mein benutzt CallBack Funktionen. (Gibt es vielleicht sogar mehr Möglichkeiten??)
Jetzt meine Frage. Hat diese Programmierung auch schon mal jemand gemacht und kennt vielleicht die Vor- und Nachteile dieser beiden Arten Daten zu transportieren??
Gruß,
Jack
jaenicke - Mo 25.05.15 19:16
Interfaces haben mehrere Vorteile. Du kannst darüber z.B. unbekannte Interfaces über eine Standard-DLL-Funktion austauschen, z.B. auch zwischen verschiedenen Addons. Zudem hast du direkt das Objekt, mit dem etwas gemacht werden soll, statt nur eine lose Funktion.
Ich habe darüber ein allgemeines DLL-Interface umgesetzt. Dort kann ich im Programm oder der DLL einfach schreiben:
            
Delphi-Quelltext    
                                        | 1:
 |   TApplicationInterface.Get<IPhysicalPrinter>('Canon ...'). ...                     | 
        
      Diese Klassenmethode gibt dann das registrierte Interface dazu zurück. Die Provider für ein Interface registrieren sich einfach bei der zentralen Verwalterklasse.
 
Martok - Di 26.05.15 00:22
Interfaces und Callbacks lösen aber ganz unterschiedliche Probleme :nixweiss:
	  |  jackle32 hat folgendes geschrieben  : | 
		  | Im Normalfall ist ja eine Dll einbinden eine One-Way Kommunikation von Exe zu Dll. | 
Im Normalfall ist eine DLL eine Dynamisch Gelinkte Bibliothek (:zwinker:), also einfach nur eine Menge Funktionen die nicht in deinem Quellcode, sondern woanders stehen. Wer davon wen aufruft, ist erstmal grundsätzlich nicht vorgegeben - die DLL kann z.B. genauso GetProcAddress aufrufen, um eine Funktion in deinem Code oder in einer weiteren DLL zu finden. Oder auch eine Variable (ja, Get
ProcAddress findet nicht nur Prozeduren, sondern alles was die DLL exportiert, und das ist prinzipiell erstmal nur ein Zeiger. Dass der meistens auf Code zeigt, ist von keiner Stelle vorgeschrieben), da kommen wir dann aber in den Bereich, der von Delphi nicht so schön durch die Sprache direkt unterstützt wird.
Ob deine DLL jetzt Interfaces oder Callbacks benutzt, hängt hauptsächlich davon ab welche Sprachen die anbinden wollten. Die "geht immer"-Lösung ist dabei C-Kompatibel zu sein und das bedeuetet dann eben, dass man keine Klassen hat. Da wird man dann also öfter mal Callback-Zeiger übergeben. Interfaces machen nur dann Sinn, wenn die andere Seite die auch kann, und dann sind wir entweder in XP/D/COM- oder sonstigem C++-Territorium.
Unabhängig davon sind Interfaces und Callbacks natürlich komplett unterschiedliche Dinge: Interfaces sind effektiv "halbe" Klassen (wir wissen also nichts über die Implementation), Callbacks sind Ereignisse (Delphi-Konvention: On***).
 
jaenicke - Di 26.05.15 07:20
	  |  Martok hat folgendes geschrieben  : | 
		  | Unabhängig davon sind Interfaces und Callbacks natürlich komplett unterschiedliche Dinge: Interfaces sind effektiv "halbe" Klassen (wir wissen also nichts über die Implementation), Callbacks sind Ereignisse (Delphi-Konvention: On***). | 
Das ist klar, aber man kann mit Interfaces auch sehr elegant eine Zwei-Wege-Kommunikation umsetzen wie mit Callbacks nur bequemer.
 
Martok - Di 26.05.15 18:59
Stimmt, wobei das halt immer drauf ankommt wie kompliziert es wird.
Nehmen wir mal an, du hast eine DLL welche einen Webserver beinhaltet. Die hat drei Ereignisse, über die sie deine Anwendung informieren möchte: Verbindung kommt rein, Request wurde gelesen und soll bearbeitet werden, Verbindung abgebrochen. Nun könnte man der DLL entweder a) 3 Callbacks übergeben, b) einen Record mit 3 Callbacks drin, oder c) man einigt sich auf ein Interface mit 3 Methoden, welches in der Hostanwendung implementiert wird und von dem die DLL dann eine Instanz bekommt. In dem Fall würde ich wohl b) oder c) nehmen.
Wenn man nur wenige oder nicht zusammengehörige Ereignisse hat, sind einfache Callbacks oft trotzdem sinnvoll. Freundlicherweise sollte der Entwickler der DLL dabei immer einen PtrInt-großen benutzerdefinierten Parameter zur Verfügung stellen, der beim Callback-Aufruf einfach zurück gespiegelt wird. Damit kann man einfach auf eine Instanz zrückschließen (
Negativbeispiel [
http://www.entwickler-ecke.de/viewtopic.php?p=693971#693971], 
Positiv [
https://git.ccs-baumann.de/Martok/sdr/blob/master/src/hardware/librtlsdr.pas#L18]-
Beispiel [
https://git.ccs-baumann.de/Martok/sdr/blob/master/src/hardware/uDriverRTLSDR.pas#L106]).
 
GuaAck - Di 26.05.15 22:57
... und es kommt auf die Zielgruppe an.
Ich arbeite in einem Projekt mit, das den FMI-Standard (Code in einer DLL, Interfacebeschreibung und vieles Andere in einer XML - als eine Möglichkeit) nutzt. Ca. 20 bekannte Simulationsprogramme bieten Import und/oder Export an.
In dem Projekt werden DLLs erstellt, die dann in vielen verschiedenen Umgebungen laufen sollen, und sie tun es.
Seht Euch mal die Homepage an, gibt vielleicht Anregungen zur Interface-Gestaltung, insbesondere, wenn es um universelle Einsetzbarkeit geht. 
Soll keine Kritik an den bisherigen Vorschlägen sein, Callback habe ich schon programmiert, Interface noch nicht, halte mich somit in der konkreten Frage nicht für einen Experten. 
Gruß
GuaAck
Entwickler-Ecke.de  based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!