Interface - Fragen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Interface - Fragen

Beitrag 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.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Interface - Fragen

Beitrag 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
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Interface - Fragen

Beitrag 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.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Interface - Fragen

Beitrag 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.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Interface - Fragen

Beitrag 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
:wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Interface - Fragen

Beitrag 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
:wink:
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 ;)
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Interface - Fragen

Beitrag 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
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Interface - Fragen

Beitrag 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.....
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Interface - Fragen

Beitrag 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 :mrgreen:
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
TroaX
Beiträge: 659
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
Wohnort: NRW
Kontaktdaten:

Re: Interface - Fragen

Beitrag 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.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box :lol:
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Antworten