Seite 2 von 2
Re: Prozedur in Variable speichern
Verfasst: 03.12.2020 11:54
von 4Planes
Das dein Beispiel funktioniert heißt leider nicht, dass es richtig ist.
Das ist ein wahrer Satz, der auf Vieles im Leben zutrifft.
Trotzdem will ich nochmal nachbohren: Sagst du in dem Post, den du verlinkt hast, nicht selber, dass das funktionieren sollte?
Re: Prozedur in Variable speichern
Verfasst: 03.12.2020 12:19
von STARGÅTE
4Planes hat geschrieben:Trotzdem will ich nochmal nachbohren: Sagst du in dem Post, den du verlinkt hast, nicht selber, dass das funktionieren sollte?
Jup, es funktioniert (scheinbar). Aber Trial and Error ist beim sauberen Programmieren fehl am Platz. Es ist gefährlich so etwas, was nicht offiziell von PureBasic "erlaubt" wird, zumindest habe ich dazu nichts in der Hilfe gefunden, in einem Programm zu nutzen.
Denn es sind später genau diese "Tricks" die vielleicht irgendwann in einem großen Projekt zu einem unerklärlichen Fehler führen, wo die Ursachenforschung dann sehr mühsam ist.
Ich kann von meiner Seite sagen, dass ich diese Möglichkeit nicht nutze, sondern je nach Situation genau die richtige Prozedur aufrufe mit der richtigen Anzahl von Parametern
Re: Prozedur in Variable speichern
Verfasst: 03.12.2020 15:25
von mk-soft
Wenn die Prototype richtig angelegt sind, Anzahl der Parameter und Parameter Typen stimmen, wenn auch die Procedure Adresse richtig zuwiesen ist, funktioniert dieses sicher.
In irgendeiner Beta Version von Purebasic ging plötzlich der Aufruf über die virtuelle Tabelle nicht mehr. Wurde aber sofort nach Meldung des Bugs sofort repariert.
Zum Beispiel:
Bei OOP-BaseClass werden Arrays verwendet um die Methoden in der virtuellen Tabelle zu hinterlegen.
Im EventDesigner V3 werden die Event Proceduren in der DataSection als virtuelle Tabelle hinterlegt und über ein Index (EventMenu, EventGadget) aufgerufen.
Beispiel GuiEventMainFile
Code: Alles auswählen
;-TOP
; ***************************************************************************
;
; Comment : EventDesigner - Common Event Main File
; Create : 2020.12.03 14.22.42
;
; Info : Do not edit this file. This file always overwrite.
;
; ***************************************************************************
; - Include Event Files
IncludeFile "GuiEventcommon.pb"
; ----
Prototype _MyPrototypeInvoke()
Structure _MyEventInvoke
Invoke._MyPrototypeInvoke[0]
EndStructure
Global *vtMyEventSizeWindow._MyEventInvoke = ?vtMyEventSizeWindow
Global *vtMyEventCloseWindow._MyEventInvoke = ?vtMyEventCloseWindow
Global *vtMyEventMenu._MyEventInvoke = ?vtMyEventMenu
Global *vtMyEventGadget._MyEventInvoke = ?vtMyEventGadget
#MyEventCountWindow = 1
#MyEventCountMenu = 2
#MyEventCountGadget = 4
; ----
Procedure _MyEventSizeWindow()
Protected WindowID = EventWindow()
Select WindowID
Case 0 To #MyEventCountWindow - 1
*vtMyEventSizeWindow\Invoke[WindowID]()
EndSelect
EndProcedure
; ----
Procedure _MyEventCloseWindow()
Protected WindowID = EventWindow()
Select WindowID
Case 0 To #MyEventCountWindow - 1
*vtMyEventCloseWindow\Invoke[WindowID]()
EndSelect
EndProcedure
; ----
Procedure _MyEventMenu()
Protected MenuID = EventMenu()
Select MenuID
Case 0 To #MyEventCountMenu - 1
*vtMyEventMenu\Invoke[MenuID]()
EndSelect
EndProcedure
; ----
Procedure _MyEventGadget()
Protected GadgetID = EventGadget()
Select GadgetID
Case 0 To #MyEventCountGadget - 1
*vtMyEventGadget\Invoke[GadgetID]()
EndSelect
EndProcedure
; ----
Procedure _MyEventGadgetNothing()
; Do Nothing
EndProcedure
; ----
; - Bind Events
BindEvent(#PB_Event_Menu, @_MyEventMenu())
BindEvent(#PB_Event_Gadget, @_MyEventGadget())
BindEvent(#PB_Event_SizeWindow, @_MyEventSizeWindow())
BindEvent(#PB_Event_CloseWindow, @_MyEventCloseWindow())
; ----
DataSection
vtMyEventSizeWindow:
Data.i @MyEventSizeWindow_WinMain()
vtMyEventCloseWindow:
Data.i @MyEventCloseWindow_WinMain()
vtMyEventMenu:
Data.i @MyEventMenu_WinMain_MenuItem_Dialog()
Data.i @MyEventMenu_WinMain_MenuItem_Exit()
vtMyEventGadget:
Data.i @MyEventGadget_WinMain_Button_DoYes()
Data.i @MyEventGadget_WinMain_Button_DoCancel()
Data.i @_MyEventGadgetNothing()
Data.i @MyEventGadget_WinMain_Calendar()
EndDataSection
; ----
Re: Prozedur in Variable speichern
Verfasst: 04.12.2020 08:53
von juergenkulow
Hallo,
Code: Alles auswählen
; Aufrufe aus einem Feld von Proceduren mit einem Pointer als Parameter
Prototype.i MyProcedure(*Param)
Procedure.i VersionPtr1(*Param)
Debug "1. Version Ptr:" +*Param
ProcedureReturn *Param
EndProcedure
Procedure.i VersionPtr2(*Param)
Debug "2. Version Ptr:" +*Param
ProcedureReturn *Param
EndProcedure
Structure Item : Proc.MyProcedure : EndStructure
Dim AufrufFeldPtr.Item(10)
For i=0 To 10
If 1=Random(2,1)
AufrufFeldPtr(i)\Proc=@VersionPtr1()
Else
AufrufFeldPtr(i)\Proc=@VersionPtr2()
EndIf
Next
*myptr=AllocateMemory(12345)
For i=0 To 10
ret=AufrufFeldPtr(i)\Proc(*myptr)
Debug ret
Next
; ; ret=AufrufFeldPtr(i)\Proc(*myptr)
; MOV r15,qword [v_i]
; MOV rbp,qword [a_AufrufFeldPtr]
; SAL r15,3
; ADD rbp,r15
; PUSH qword [rbp]
; SUB rsp,8
; PUSH qword [p_myptr]
; POP rdi
; CALL qword [rsp+8]
; ADD rsp,8
; ADD rsp,8
; MOV qword [v_ret],rax
Code: Alles auswählen
; Aufrufe mit verschiedenen Parametertypen unter Linux x64
; ; VersionDouble(12.345)
; PUSH qword [D1]
; MOVSD xmm0,qword [rsp]
; ADD rsp,8
; CALL _Procedure0
; ; VersionFloat(12.345)
; FLD dword [F1]
; SUB rsp,8
; FSTP dword [rsp]
; MOVSS xmm0,dword [rsp]
; ADD rsp,8
; CALL _Procedure4
; ; VersionString("12.345")
; MOV rax,_S1
; PUSH rax
; POP rdi
; CALL _Procedure6
; ; VersionLong(12345)
; MOV rax,12345
; MOV rax,rax
; PUSH rax
; POP rdi
; CALL _Procedure8
; ; VersionQuad(12345)
; PUSH qword 12345
; POP rdi
; CALL _Procedure10
; ; VersionPtr(12345)
; PUSH qword 12345
; POP rdi
; CALL _Procedure12