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

Re: Anfänger Problem mit "Interface"
Verfasst: 28.04.2010 18:37
von Josh
scheiße, war wieder einer schneller
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

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

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
Du bist doch noch nicht so alt das Du nicht mehr umlernen kannst
Gerade im Anfängerforum wäre ein korrekter Code wünschenswert, oder lasse das einfach weg.
Ich freu mich schon auf das Beispiel
Gruß
Thomas