Seite 1 von 4
Interface - Fragen
Verfasst: 15.08.2017 11:03
von Bisonte
Hallo.
Ich experimentiere mit der Funktion Interface herum.
Es gibt dort, genauso wie bei Structure, ein "Extends" um ein vorhandenes Interface zu erweitern.
Das vTable (also die Definition der einzelnen Interfaceprozeduren) liegt in einer DataSection.
Kleines Beispiel:
Code: Alles auswählen
Interface iInterface
Free.i()
EndInterface
Structure s_iInterface
vTable.i
EndStructure
Procedure.i _Free(*this.s_iInterface)
EndProcedure
DataSection
vTable_iInterface:
Data.i @_Free()
EndDataSection
So habe ich das in den meisten Beispielen, die ich fand gesehen. Als einzelnes Interface (z.B. in einem Modul)
klappt das. Meine Frage nun :
Wenn ich ein Interface mit Extends "erweiter", wie muss dann die DataSection und das "vTable" aussehen ?
Wieder eine Anschauung :
Code: Alles auswählen
Interface iInterface
Free.i()
EndInterface
Interface iInteger Extends iInterface
Get.i()
Neu.i()
EndInterface
Interface iString Extends iInterface
Neu.s()
EndInterface
Structure s_iInterface
vTable.i
EndStructure
Procedure.i _Free(*this.s_iInterface)
EndProcedure
Procedure.i _GetInteger(*this.s_iInterface)
EndProcedure
Procedure.i _NeuInteger(*this.s_iInterface)
EndProcedure
Procedure.s _NeuString(*this.s_iInterface)
EndProcedure
Procedure.i CreateInteger()
Protected *this.s_iInterface = AllocateStructure(s_iInterface)
If *this
*this\vTable = ; ?
EndIf
ProcedureReturn *this
EndProcedure
Procedure.i CreateString()
Protected *this.s_iInterface = AllocateStructure(s_iInterface)
If *this
*this\vTable = ; ?
EndIf
ProcedureReturn *this
EndProcedure
DataSection
vTable_iInterface:
Data.i @_Free()
; ?
EndDataSection
Es handelt sich um ein Interface, das Standard Prozeduren enthalten soll, die in allen Interfaces am Ende auch sein sollen.
Und ich denke das "Extends" genau dafür gemacht wurde.
Re: Interface - Fragen
Verfasst: 15.08.2017 11:49
von mhs
Die vTable muss genauso aussehen wie das fertige Interface.
Das bedeutet, dass du für jedes Interface eine separate vTable brauchst. Das kannst du z.B. mit einem Makro so gestalten:
Code: Alles auswählen
Interface iInterface
Free.i()
EndInterface
Interface iInteger Extends iInterface
Get.i()
Neu.i()
EndInterface
Interface iString Extends iInterface
Neu.s()
EndInterface
Structure s_iInterface
vTable.i
Name.s
EndStructure
Procedure.i _Free(*this.s_iInterface)
Debug *this\Name + ": Free"
EndProcedure
Procedure.i _GetInteger(*this.s_iInterface)
Debug *this\Name + ": Get I"
EndProcedure
Procedure.i _NeuInteger(*this.s_iInterface)
Debug *this\Name + ": Neu I"
EndProcedure
Procedure.s _NeuString(*this.s_iInterface)
Debug *this\Name + ": Neu S"
EndProcedure
Procedure.i CreateInteger()
Protected *this.s_iInterface = AllocateStructure(s_iInterface)
If *this
*this\vTable = ?vTable_iInteger
*this\Name = "Integer" ; for demonstration purposes...
EndIf
ProcedureReturn *this
EndProcedure
Procedure.i CreateString()
Protected *this.s_iInterface = AllocateStructure(s_iInterface)
If *this
*this\vTable = ?vTable_iString
*this\Name = "String"
EndIf
ProcedureReturn *this
EndProcedure
obj1.iInteger = CreateInteger()
obj1\Free()
obj1\Get()
obj1\Neu()
obj2.iString = CreateString()
obj2\Free()
obj2\Neu()
Macro vTable_iInterface
Data.i @_Free()
EndMacro
DataSection
vTable_iInteger:
vTable_iInterface
Data.i @_GetInteger()
Data.i @_NeuInteger()
vTable_iString:
vTable_iInterface
Data.i @_NeuString()
EndDataSection
Re: Interface - Fragen
Verfasst: 15.08.2017 11:54
von Bisonte
Ah ok. Also im vTable muss dann jede einzelne Prozedur (auch die im "Standard" sind) wieder
aufgeführt sein (natürlich auch in der gleichen Reihenfolge).
Danke.
Re: Interface - Fragen
Verfasst: 15.08.2017 13:04
von GPI
Bisonte hat geschrieben:Ah ok. Also im vTable muss dann jede einzelne Prozedur (auch die im "Standard" sind) wieder
aufgeführt sein (natürlich auch in der gleichen Reihenfolge).
Danke.
Exakt. Wobei du nicht zwingend die gleiche Prozeduren nutzen musst, sondern auch andere verwenden kann. Und jup, man muss zwingend auf die Reihenfolge drauf achten, sonst hat man ein Problem....
Aus den Grund haben einige hier sich "Verwaltungsmodule" für Klassen geschrieben, die die Erstellung der VT überprüfen.
Re: Interface - Fragen
Verfasst: 15.08.2017 14:33
von mk-soft
Die vTable muss nicht in einer DataSection liegen. Für fest implementierte Interfaces macht diese sinn.
Man kann auch die vTable in ein Array (Dim) packen und diese zur Laufzeit füllen.
Die Methode verwende ich bei meinen Modul BaseClass und BaseClassDispatch. Siehe link
Re: Interface - Fragen
Verfasst: 15.08.2017 15:19
von Bisonte
mk-soft hat geschrieben:Die vTable muss nicht in einer DataSection liegen. Für fest implementierte Interfaces macht diese sinn.
Man kann auch die vTable in ein Array (Dim) packen und diese zur Laufzeit füllen.
Die Methode verwende ich bei meinen Modul BaseClass und BaseClassDispatch. Siehe link
Wohow.... Ich wollt mich da langsam ranpirschen
Wenn ich mir den Code ansehe, ertrinke ich gleich...
Zumal die OOP - Bezeichnungen immer noch für mich böhmische Dörfer darstellen. Gruss an die Leute der Dörfer in Böhmen
Re: Interface - Fragen
Verfasst: 15.08.2017 16:34
von mk-soft
Die BaseClass ist ein wenig gewachsen...
- Kompatible zu IUnknown
- Threadsafe
- Methodennamen für späte Bindung (IDispatch)
- Kapsel alles in Procedure weil sonst bei Modulen der Code als DLL abstürzt
- etc
Re: Interface - Fragen
Verfasst: 15.08.2017 19:54
von GPI
Bisonte hat geschrieben:Wohow.... Ich wollt mich da langsam ranpirschen
Wenn ich mir den Code ansehe, ertrinke ich gleich...
Zumal die OOP - Bezeichnungen immer noch für mich böhmische Dörfer darstellen. Gruss an die Leute der Dörfer in Böhmen
Ach, wenn du fragen hast, frag doch einfach. So kompliziert ist das ganze eigentlich nicht. Die VT-Tabelle ist halt eine Adress-Liste der Methoden. Und diese Methoden sind prinzipiell einfach Proceduren, die als ersten Parameter das Objekt enthält.
Ein Objekt ist prinzipiell eine Structur, die die Objekt-Daten (Member/Properties) enthalten. Wobei der erste Eintrag zwingend die Adresse der VT-Tabelle sein muss.
Leider weigert sich Fred, die Klassenverwaltung fest in PB zu übernehmen, so das man das selbst machen muss. Und wenn man was allgemein formuliert, dann wirds schnell mal größer. Meine Lösung ist hier:
http://www.purebasic.fr/german/viewtopi ... =8&t=30296
Es ist halt nicht so leicht, automatisch rauszufinden, wie die Methoden heißen, ob es in Interface vorhanden ist etc. Wenn man jetzt Vererbung ermöglichen will, wirds wieder ein Tick größer. Dann kommen Konstruktoren und Destruktoren hinzu.....
Re: Interface - Fragen
Verfasst: 15.08.2017 20:54
von Bisonte
naja wie gesagt. anpirschen.... diese ganzen ausdrücke erarbeite ich mir grad...
wobei das meiste was ich zu lesen kriege auf englisch ist, und das ist halt nicht native language...
dauert also ein bisserl länger, wir werden ja nich jünger
Aber wenns drückt dann schrei ich schon
Re: Interface - Fragen
Verfasst: 15.08.2017 21:06
von TroaX
Also wenn es nur die Sprache ist, dann schau mal hier:
http://openbook.rheinwerk-verlag.de/oop/
Finde ich als Einstieg recht gut.