Seite 1 von 2

Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 17:45
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

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 18:28
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:

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 18:37
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

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 18:53
von spacewalkerDE
hm...kommt mir alles doch recht kompliziert vor.. aber na ja, werde ich mir mal genauer ansehen.

Danke für die Antworten

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 19:03
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:

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 19:21
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.

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 19:48
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

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 19:51
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

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 20:07
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 ^^

Re: Anfänger Problem mit "Interface"

Verfasst: 28.04.2010 20:14
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