Page 1 of 1
It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 5:33 pm
by Wolfram
Can someone tell me is it possible to call a procedure this way…?
Code: Select all
Procedure Test_A()
Debug "A"
EndProcedure
Procedure Test_B()
Debug "B"
EndProcedure
Dim MyFnctions.i(100)
MyFnctions(0) = @Test_A()
MyFnctions(1) = @Test_B()
;can I call Test_A() by using the stored address in MyFnctions(0)???
Re: It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 5:39 pm
by TI-994A
Like this:
Code: Select all
Procedure Test_A()
Debug "A"
EndProcedure
Procedure Test_B(t.s)
Debug t
EndProcedure
Dim MyFnctions.i(100)
MyFnctions(0) = @Test_A()
MyFnctions(1) = @Test_B()
CallFunctionFast(MyFnctions(0))
CallFunctionFast(MyFnctions(1), @"B")
Re: It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 5:45 pm
by Wolfram
Thanks!
I hope it is what it suggested - fast.

Re: It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 6:46 pm
by wilbert
Wolfram wrote:I hope it is what it suggested - fast.

When it comes to speed, I think using Prototype would be a little bit faster.
Re: It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 11:16 pm
by netmaestro
Is that old thing still here? Should be deprecated by now imho. It's limited to integers as parameter, not so for prototypes:
Code: Select all
Prototype ThisKindOfProc(a.i, b.s)
Procedure DoSomeOfThis(a.i, b.s)
Debug "My name is " + b
Debug "I am " + Str(a) + " years old"
EndProcedure
Global This.ThisKindOfProc = @DoSomeOfThis()
This(100, "Hillary")
I vote with Wilbert on this one.
Re: It is possible to call a procedure by using its address?
Posted: Tue Nov 08, 2016 11:42 pm
by Wolfram
Thanks for the Prototype example, but my idea was to call a Procedure depends of a result.
Normally you must use select to run the right Procedure depends of the result.
This is a lot of work for me and the computer, if I have 100 different results.
Code: Select all
Procedure Test_A()
Debug "A"
EndProcedure
Procedure Test_B()
Debug t
EndProcedure
Dim MyFnctions.i(100)
MyFnctions(0) = @Test_A()
MyFnctions(1) = @Test_B()
CallFunctionFast(MyFnctions(result))
Re: It is possible to call a procedure by using its address?
Posted: Wed Nov 09, 2016 6:20 am
by TI-994A
Wolfram wrote:Thanks for the Prototype example, but my idea was to call a Procedure depends of a result.
Yes; sadly, prototypes can't be used in arrays, lists, or maps. If you need to pass values other than integers with
CallFunctionFast(), simply store them in a string, pass the string address, and read the value with the corresponding
ValX() function.
Code: Select all
Procedure passTypes(nbr, txt.s, flt.s)
Debug nbr
Debug txt
Debug ValF(flt)
EndProcedure
myFunc = @passTypes()
CallFunctionFast(myFunc, 123, @"Hello!", @"456.789")
Not very elegant, but it's a viable workaround.

Re: It is possible to call a procedure by using its address?
Posted: Wed Nov 09, 2016 7:37 am
by wilbert
Prototype with Runtime example
Code: Select all
; >> Runtime Procedures <<
Runtime Procedure Fn0()
Debug "A"
EndProcedure
Runtime Procedure Fn1(n)
Debug n
EndProcedure
Runtime Procedure Fn2(n)
Debug n*n
EndProcedure
Runtime Procedure Fn3(s.s)
Debug s
EndProcedure
Runtime Procedure Fn4(s.s)
Debug LCase(s)
EndProcedure
Runtime Procedure Fn5(s.s)
Debug UCase(s)
EndProcedure
; >> Prototypes for different kind of functions <<
Prototype FnProto()
Prototype FnProto1Arg(arg1.i)
Prototype FnProto1StrArg(arg1.s)
; >> Structure with all kind of function prototypes <<
Structure FnStruct
StructureUnion
FnAddr.i
Call.FnProto
Call1Arg.FnProto1Arg
Call1StrArg.FnProto1StrArg
EndStructureUnion
EndStructure
; >> Count Runtime Procedures <<
FnCount = 0
While IsRuntime("Fn" + Str(FnCount) + "()")
FnCount + 1
Wend
; >> Runtime Procedures to Array <<
If FnCount
Dim Fn.FnStruct(FnCount - 1)
i = 0
While i < FnCount
Fn(i)\FnAddr = GetRuntimeInteger("Fn" + Str(i) + "()")
i + 1
Wend
EndIf
; >> Test the procedures <<
Fn(0)\Call()
Fn(1)\Call1Arg(100)
Fn(2)\Call1Arg(100)
Fn(3)\Call1StrArg("Prototype method")
Fn(4)\Call1StrArg("Prototype method")
Fn(5)\Call1StrArg("Prototype method")
Prototype without Runtime example
Code: Select all
Procedure Test_A()
Debug "A"
EndProcedure
Procedure Test_B(n)
Debug n
EndProcedure
Procedure Test_C(n)
Debug n*n
EndProcedure
Procedure Test_D(s.s)
Debug s
EndProcedure
Prototype FnProto()
Prototype FnProto1Arg(arg1.i)
Prototype FnProto1StrArg(arg1.s)
Structure FnStruct
StructureUnion
FnAddr.i
Call.FnProto
Call1Arg.FnProto1Arg
Call1StrArg.FnProto1StrArg
EndStructureUnion
EndStructure
Dim MyFnctions.FnStruct(100)
MyFnctions(0)\FnAddr = @Test_A()
MyFnctions(1)\FnAddr = @Test_B()
MyFnctions(2)\FnAddr = @Test_C()
MyFnctions(3)\FnAddr = @Test_D()
MyFnctions(0)\Call()
MyFnctions(1)\Call1Arg(100)
MyFnctions(2)\Call1Arg(100)
MyFnctions(3)\Call1StrArg("Prototype method")
Another way would be to use DataSection for the function pointers but it does look a bit more complicated I think.
Code: Select all
Procedure Test_A()
Debug "A"
EndProcedure
Procedure Test_B(n)
Debug n
EndProcedure
Procedure Test_C(n)
Debug n*n
EndProcedure
Procedure Test_D(s.s)
Debug s
EndProcedure
DataSection
FnAddrTable:
Data.i @Test_A(), @Test_B(), @Test_C(), @Test_D()
EndDataSection
Prototype FnProto()
Prototype FnProto1Arg(arg1.i)
Prototype FnProto1StrArg(arg1.s)
Structure FnStruct
Call.FnProto[0]
Call1Arg.FnProto1Arg[0]
Call1StrArg.FnProto1StrArg[0]
EndStructure
*F.FnStruct = ?FnAddrTable
*F\Call[0]()
*F\Call1Arg[1](100)
*F\Call1Arg[2](100)
*F\Call1StrArg[3]("Prototype method")