Anfänger Problem mit "Interface"

Anfängerfragen zum Programmieren mit PureBasic.
spacewalkerDE
Beiträge: 3
Registriert: 28.04.2010 17:18

Anfänger Problem mit "Interface"

Beitrag von spacewalkerDE »

Hallo,

ich versuche etwas mit dem Interface Befehl zu spielen bzw. diesen prinzipiell zu verstehen.

Folgenden Code habe ich mir zusammengesucht :

Code: Alles auswählen

Interface Rechnen
  Plus    (x1,x2)
  Minus   (x1,x2)
EndInterface 


Procedure Rechnen_Plus(*This.Rechnen, x1, x2)  ;<<--- muss hier "This.rechnen" stehen ?
    ProcedureReturn x1+x2
EndProcedure 

Procedure Rechnen_minus(*This.Rechnen, x1, x2)
    ProcedureReturn x1-x2
EndProcedure 


;************************

MyRechnen.Rechnen = Rechnen_CreateObject()         ; <<---Fehler "Not a function, array or macro"

x = Rechnen\Plus(2,2)                ;<<----- wäre das korrekt ?
y = Rechnen\Minus (10,1)

print Str(x)
Ich erhalten den Fehler "Not a function, array or macro" in der Zeile MyRechnen.Rechnen = Rechnen_CreateObject()

Ich denke, man kann erkennen was ich das machen wollte, nämlich einfach ein Objekt "Rechnen" erstellen das die Methoden "plus" und "Minus" zur Verfügung stellt....

Wie müsste ich den Code ändern, damit so was einfaches geht?

Danke
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Anfänger Problem mit "Interface"

Beitrag von ts-soft »

Code: Alles auswählen

EnableExplicit

Interface Rechnen
  Destroy () ; damit wir den Objektspeicher auch wieder freigeben können!
  Plus    (x1, x2)
  Minus   (x1, x2)
EndInterface

Structure Rechnen_Template
  *vTable
  ; weitere Objectvariablen
EndStructure

Procedure New_RechnenObject() ; Objekt erstellen (Objektspeicher allokieren)
  Protected *this.Rechnen_Template
  
  *this = AllocateMemory(SizeOf(Rechnen_Template))
  If *this
    *this\vTable = ?VTable_RechnenClass
    ; weitere Initialisierungen
    ProcedureReturn *this
  EndIf
EndProcedure

Procedure Rechnen_Destroy(*This.Rechnen_Template)
  FreeMemory(*This)
EndProcedure

Procedure Rechnen_Plus(*This.Rechnen_Template, x1, x2)
    ProcedureReturn x1 + x2
EndProcedure

Procedure Rechnen_Minus(*This.Rechnen_Template, x1, x2)
    ProcedureReturn x1 - x2
EndProcedure

DataSection
  VTable_RechnenClass: ; Methoden, Reihenfolge muß mit Interface übereinstimmen!
  Data.i @Rechnen_Destroy()
  Data.i @Rechnen_Plus()
  Data.i @Rechnen_Minus()
EndDataSection

Define.Rechnen *obj

*obj = New_RechnenObject()
Debug *obj\Plus(20, 10)
Debug *obj\Minus(1000, 100)
*obj\Destroy() : *obj = 0
Noch einfacher kann man den Code nicht erstellen :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Anfänger Problem mit "Interface"

Beitrag von Josh »

scheiße, war wieder einer schneller :cry:

edit: erweitert auf ein com-objekt

Code: Alles auswählen

Structure udtRechnen
  *VTable
  cntRef.l
EndStructure

Interface IRechnen Extends IUnknown
  Plus    (x1,x2)
  Minus   (x1,x2)
EndInterface

Procedure.l QueryInterface (*This.udtRechnen, *iid.IID, *Object.Integer)

;Standardzuweisungen auf eigenes Objekt (ggf. noch erweitern mit IID, die erwartet wird)
  If CompareMemory(*iid, ?IID_IUnknown, 16)
    *Object\i = *This
    *This\cntRef + 1
    ProcedureReturn #S_OK
  EndIf

;Unbekanntes Interface
  MessageRequester("Intern" , "QueryInterface hat nach einem nicht impletierten Interface angefragt")
  *Object\i = 0
  ProcedureReturn #E_NOINTERFACE

EndProcedure
Procedure.l AddRef         (*This.udtRechnen)

  *This\cntRef + 1
  ProcedureReturn *This\cntRef

EndProcedure
Procedure.l Release        (*This.udtRechnen)

    *This\cntRef - 1

    If *This\cntRef < 1
      FreeMemory(*This)
      ProcedureReturn 0
    EndIf

    ProcedureReturn *This\cntRef

  EndProcedure
Procedure   Rechnen_Plus   (*This.udtRechnen, x1, x2)  ;<<--- muss hier "This.rechnen" stehen ?

    ProcedureReturn x1+x2

EndProcedure
Procedure   Rechnen_minus  (*This.udtRechnen, x1, x2)

    ProcedureReturn x1-x2

EndProcedure

Procedure Rechnen_New()
  Define *This.udtRechnen

  DataSection

    VTable:
    Data.i @QueryInterface()
    Data.i @AddRef()
    Data.i @Release()
    Data.i @Rechnen_Plus()
    Data.i @Rechnen_minus()

    IID_IUnknown: ; {00000000-0000-0000-C000-000000000046}
    Data.l $00000000
    Data.w $0000,$0000
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46

  EndDataSection

  *This = AllocateMemory(SizeOf(udtRechnen))
  If *This = 0 : MessageRequester ("", "Zu wenig Speicher") : End : EndIf

  *This\VTABLE   = ?VTable
  *This\cntRef + 1

  ProcedureReturn *This

EndProcedure

;************************

Define *Rechnen.IRechnen

;Com-Objekt erstellen
*Rechnen = Rechnen_New()

;Com-Objekt benutzen
Debug *Rechnen\Plus(2,2)
Debug *Rechnen\Minus (10,1)

;Com-Objekt wieder frei geben
*Rechnen\Release()
*Rechnen = 0
Zuletzt geändert von Josh am 29.04.2010 09:17, insgesamt 5-mal geändert.
spacewalkerDE
Beiträge: 3
Registriert: 28.04.2010 17:18

Re: Anfänger Problem mit "Interface"

Beitrag von spacewalkerDE »

hm...kommt mir alles doch recht kompliziert vor.. aber na ja, werde ich mir mal genauer ansehen.

Danke für die Antworten
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Anfänger Problem mit "Interface"

Beitrag von ts-soft »

spacewalkerDE hat geschrieben:hm...kommt mir alles doch recht kompliziert vor.. aber na ja, werde ich mir mal genauer ansehen.

Danke für die Antworten
Im Vergleich zu den COM-Objekten, nach denen Du im anderem Thread gefragt hast, ist dies
sehr sehr sehr sehr viel einfacher :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Anfänger Problem mit "Interface"

Beitrag von Josh »

ts-soft hat geschrieben:Im Vergleich zu den COM-Objekten, nach denen Du im anderem Thread gefragt hast, ist dies
sehr sehr sehr sehr viel einfacher :mrgreen:
ach so viel komplizierter ist ein com-objekt auch wieder nicht. habe meinen code oben mal auf ein com-objekt erweitert. es fehlen halt noch die methoden und ein eigenes interfaceId, damit es auch einen sinn macht, aber im prinzip erfüllt es alle vorraussetzungen die ein com-objekt ausmachen und jede win-api die ein com-interface von dir verlangt, wird dieses auch fressen.
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Re: Anfänger Problem mit "Interface"

Beitrag von Fluid Byte »

Srod aus dem englischen Forum hat diesbezüglich ein sehr gutes Tuturial geschrieben.

Einfacher wirst du es nicht serviert bekommen: http://www.purecoder.net/oop.zip
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Anfänger Problem mit "Interface"

Beitrag von ts-soft »

@Josh
Kannste das Beispiel noch ausbauen und in Tipps & Tricks posten?

Soweit vervollständigen, das man zum Beispiel eine DLL draus machen kann
und diese im System registrieren.

PS: Schon wieder diese "falschen" Procedure.l

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Anfänger Problem mit "Interface"

Beitrag von Josh »

ts-soft hat geschrieben:Kannste das Beispiel noch ausbauen und in Tipps & Tricks posten?
Soweit vervollständigen, das man zum Beispiel eine DLL draus machen kann und diese im System registrieren.
kann ich machen. habe allerdings noch nichts mit systemregistrierung gemacht, nur dort, wo mir windows zur kommunikation vorschreibt, dass ich ein com-object zur verfügung stellen muss. da ist dann ja das interface und die interfaceId schon vorgegeben. aber ich denke, in einer dll wirds auch nicht viel anders sein. wird nicht viel mehr werden als obiges beispiel, aber ich werds mal in ein konkretes beispiel einbauen.
ts-soft hat geschrieben:PS: Schon wieder diese "falschen" Procedure.l
warum soll das .l falsch sein? es ist ein l und bleibt ein l. da wird kein pointer zurückgegeben und warum soll es dann in einem 64bit system auf einmal was anderes sein als auf einem 32bit system? ich verwende .i grundsätzlich nur für pointers, dann ist es auch da schon für mich auf den ersten blick klar, dass es sich um einen pointer handelt. die 5ms die ein l auf einem 64bit system bei einer mio durchläufen vieleicht länger braucht, sind mir eigentlich sch... egal ^^
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Anfänger Problem mit "Interface"

Beitrag von ts-soft »

Die Rückgabe eines Integers ist nunmal das einfachste für jede Funktion. Einfach auf EAX oder RAX
pushen. Sind vielleicht nur wenige ms, aber es ist einfach nicht der Standard-Typ, der dort hingehört :mrgreen:
Du bist doch noch nicht so alt das Du nicht mehr umlernen kannst :twisted:
Gerade im Anfängerforum wäre ein korrekter Code wünschenswert, oder lasse das einfach weg.

Ich freu mich schon auf das Beispiel :allright:

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten