Methode zu Object
Übersicht

sinjinBetreff: Methode zu Object |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wie bekomme ich die Physikalische Addresse eine Methode heraus.
Bei einer Funktion geht ja folgendes: Code: [AUSKLAPPEN] function test:object() print "test" endfunction local run:object()=test run Eine Methode ist ja nichts anderes als eine Funktion mit Übergabewert (self). Wie geht es nun mit Methoden? Bei Folgendem Code bekomme ich folgenden fehler: Unable to convert from 'Object()' to 'Object()' Code: [AUSKLAPPEN] type test1 method draw:object() print "test" endmethod endtype global t1:test1=new test1 global aha:object() aha=t1.draw 'test1.draw aha Wenn es so nicht geht, sollte es mit Assembler gehen indem man es ungefähr so macht: Code: [AUSKLAPPEN] function callmethod(caller:object(),instance:object) _callmethod caller,instance endfunction type test1 method draw:object() print "test" endmethod endtype global t1:test1=new test1 global aha:object() callmethod t1.draw,t1 Und der Assemblercode dazu müsste ungefähr so aussehen, leider kennt er dword ptr nicht... Code: [AUSKLAPPEN] format MS COFF public __callmethod __callmethod: push ebp sub esp,8 call [dword ptr ss:esp] pop ebp ret |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] Import BRL.Reflection
Type MyType Global C:Int = 7 Method AMethod:Int(B:Int) Return B+C EndMethod End Type Local AType:MyType = New MyType Local AMethod:Int( this:MyType, B:Int) = GetMethodPointer( AType, "AMethod") Print AMethod( AType, 6) Function GetMethodPointer:Byte Ptr( obj:Object, name:String) Extern "C" Function bbRefMethodPtr:Byte Ptr( obj:Object, index:Int ) EndExtern Local t:TTypeId = TTypeId.ForObject(obj) If Not t Then Return Null Local m:TMethod = t.FindMethod(name) If Not m Then Return Null Return bbRefMethodPtr( obj, m._index) EndFunction Allerdings stellt sich mir die Frage nach dem Sinn eines Methodpointers schon ein wenig. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke, ich finde es wesentlich flexibler, da so mehr oder weniger die Methoden-Namen wegfallen anstatt es so zu machen:
Code: [AUSKLAPPEN] type tsupertype method draw() endmethod endtype type tt1 extends tsupertype field aa%=5 method draw() print "tt1 "+aa endmethod endtype type tt2 extends tsupertype field aa$="aha" method draw() print "tt2 "+aa endmethod endtype global supertype:tsupertype[2] supertype[0]=new tt1 supertype[1]=new tt2 supertype[0].draw supertype[1].draw Ausserdem hat es den Vorteil, das man zb Raumschiffen statt Geschwindigkeit, Feuerkraft etc auch noch BELIEBIGEN Code mitgeben kann. Und man kann sich einige IF's sparen. Normal läuft es ja so ab (Pseudocode): repeat if button.pressed then xor button.on,1 if button.on then do something forever Wenn man nun ein Array mit Methoden/Funktionen hat, fällt die zweite IF-Abfrage weg: repeat if button.pressed then add to arrayoffunctions(do something) call arrayoffunctions forever Das mag im ersten Moment übertrieben sein, aber wenn man ein richtig fettes Programm hat, bringt das mit Sicherheit einiges. |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Methodpointer sind allerdings deutlich weniger performant, da per Reflection aufgelöst. Da gefällt mir persönlich der ansatz mit der Überladung/ Vererbung deutlich besser. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich kenn mich ja nicht mit Reflection aus, Leute, aber wenn du einen Pointer auf eine Methode hast, dann kann der nicht "weniger performant" sein als irgendein anderer Funktionspointer ![]() Ich glaub mit meinem ObjectEx-Modul könnte sich die Adresse auch auslesen lassen... Mal sehen. |
||
![]() |
Silver_Knee |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn du wirklich einzelnen Objekten Code mitgeben willst, kannst du das auch mit Funktionspointern machen:
BlitzMax: [AUSKLAPPEN]
Wenn du die externe Funktion so in eine Methode einbettest, kannst du in der Klasse den Rückgabewert bzw die Eingabedaten noch validieren/auswerten. |
||
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Silver_Knee
Mir geht es ja eigentlich darum nicht für jede Methode noch eine Funktion anzulegen, das finde ich zu doppelt gemoppelt. Das Mulipliziert sich zu schnell, 3 Typen á 3 Methoden sind 9 extra Funktionen. Deshalb kam ich ja anfangs auch auf die Idee nur 1 Funktion zu schreiben die den Job übernimmt, und wenns BlitzBasic so nicht kann dann eben in Assembler, leider kann ich kaum C. Zu DOS-Zeiten habe ich nur Assembler programmiert, aber mit Windows habe ich es dann nach und nach aufgegeben. @Thunder Bin gespannt ![]() Aber danke an alle die sich dran probieren! Vielleicht kommt ja noch von jemanden eine recht einfache Lösung. |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist wahrscheinlich auch nicht das was du suchst, aber das ist ein Ansatz den ich vor einer Weile für Event-Handler ähnlich wie bei .NET umgesetzt habe. Bei den Methoden funktioniert das auch via Reflection (wobei die Auflösung nur beim Hinzufügen einer Methode geschieht, beim Aufruf nicht mehr, da zwischengespeichert).
https://www.blitzforum.de/foru...hp?t=39969 Im wesentlichen kann man das dann so verwenden: BlitzMax: [AUSKLAPPEN] Local event:TMaxEvent = New TMaxEvent Naja, dachte ich poste es einfach mal ![]() PS: Etwas speziell daran ist, dass immer eine Funktion mit der Signatur (quellObjekt:Object, eventArgs:TMaxEventArgs) erwartet wird. Das kommt daher, weil wie gesagt .NET das Vorbild war. Aber das könnte man ja schnell anpassen. |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
@sinjin: Frage: könntest du nochmal versuchen, zu erklären, warum es dir mit den Methoden-Pointern sinnvoll vorkommt? Ich habe im Moment das Gefühl, dass du momentan noch die high-level-Konstrukte nicht so begreifst, wie man sie verwendet - bitte nimm das nicht persönlich ![]() Ich bin mir ziemlich sicher, dass man die meisten sinnvollen Sachen in BlitzMax verwirklichen kann, ohne auf Assembler zurückzugreifen (ja, ich tu es auch gern - siehe ObjectEx oder mein Tutorial zu BlitzMax & C/asm). BlitzMax ist auch gar nicht so ineffizient. Kannst dir ja mal in den .bmx Ordnern, die automatisch generiert werden die *.release.*.s-Dateien anschauen, das ist der Assemblercode. Und zu deinem Assemblercode ganz am Anfang: Das dword ptr kannst du dir sparen und ss: auch, weil das Stacksegment bei den Stackregistern sowieso verwendet wird (außerdem ist auf den meisten Betriebssystemen ds = es = ss). In FASM sind die eckigen klammern das gleiche, wie wenn man ptr davor schreibt - also "call [edx]" = "call ptr edx" Siehe auch http://flatassembler.net/docs.php?article=manual |
||
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
Was du für das was du da machen willst eigentlich brauchst ist Überladung.
Wenn du ein Objekt haben willst, dass auf eine Funktion anders reagiert als andere Objekte dieser Art, dann mach einen Untertyp des Originaltyps, bei dem du die eine Funktion mit der neuen Funktion überlädst. Das ist wesentlich sauberer. Wenn man mit Assembler beginnt, dann lernt man den Code zu verunstalten um einzelne Prozessorzyklen an Performance herauszukitzeln. Das war in den Neunzigerjahren notwendig und ist es immer noch, wenn man auf einem ATMega oder ähnlichem programmiert. Auf einem modern i3/i5/i7 oder selbst noch auf einem Core2-Prozessor ist das reine Zeitverschwendung. Dafür sorgst du so dafür, dass dein Code absolut unleserlich wird, da man zeitweise gar nicht mehr weiß, was diese Funktion jetzt tut, die einen Funktionspointer ausführt, der schon fünf mal herumgeschupft wurde. Außerdem optimiert der Compiler viel für dich. Wenn du zu viele Mikrooptimierungen verwendest, dann kommt der Compiler oft nicht mehr mit, mit dem Chaos, dass du da tust, und kann nicht mehr optimieren. Funktionspointer lassen sich z.B. oft nicht inlinenen, da erst zur Laufzeit fest steht, auf welche Funktion sie zeigen, was bei kleinen Funktionen viel Performance bringen würde. Versuche also besser, wenn du BlitzMax programmierst, es so zu verwenden, wie man BlitzMax verwenden soll, nicht so wie du sonst Assembler programmierst. Du machst deinen Code so nicht schneller, aber wohl unleserlicher. Mit etwas Pech wird es dadurch sogar noch langsamer. @Reflection: Sobald du den Funktionspointer hast ist es gleich schnell wie einen Funktionspointer direkt zu verwenden. Einzig das Bekommen des Funktionspointers über Reflection ist langsam. |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Lobby |
![]() Antworten mit Zitat ![]() |
---|---|---|
Psst, DAK, ich glaube du meinst Überschreiben. | ||
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jaja, ist ja gut, ich habe überschreiben gemeint^^
Das kommt davon, wenn man hald immer nur auf Englisch programmiert (@Override ist die Annotation dazu in Java). |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
sinjin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Thunder Ich finde das sinnvoll weil man halt durch die Typen sauberer Programmieren kann (OOP, logisch). Ich könnte schliesslich auch alle Variablen in ein riesen Array packen und alles in Funktionen aufsplitten. In Assembler fand ich es früher super, man legt ein Struct(Type) an, und war von den dazu gehörigen Funktionen total unabhängig. Damals habe ich zb. für eine Datei-Struktur ein Struct gehabt, und je nachdem ob Windows gerade läuft, die Funktionen für die langen Dateinamen ausgetauscht.
Ich weiss sehr wohl, dass man ds bzw ss nicht davor schreiben muss, ich finde es aber übersichtlicher, das Ergebnis verändert sich dadurch nicht und der Compiler kann so oder so nichts optimieren. Schlisslich kann ich in ds auch was anderes reinschrieben. Ich habe mein Assemblerzeug mal hochgeladen. Alleine der Source für meine Units ist 500kb gross...ach, das waren Zeiten. http://www.file-upload.net/dow...s.rar.html Das eine oder andere davon ist sich auch für euch interessant. Gestern habe ich Freebasic entdeckt, das finde ich ja geil: Keyword ASM und los gehts ![]() |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Funktion kannst du ja auswechseln wenn du Funktionspointer verwendest.
Wie das mit Methoden geht, hat Silver_Knee in einem Beispiel schon gezeigt. Werde mir das mal durchsehen ![]() |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn Du aber wirklich sauberes OOP willst lässt Du die Finger möglichst von Pointern weg, die untergraben nämlich das Paradigma gewaltig. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group