It is possible to call a procedure by using its address?

Just starting out? Need help? Post your questions and find answers here.
Wolfram
Enthusiast
Enthusiast
Posts: 604
Joined: Thu May 30, 2013 4:39 pm

It is possible to call a procedure by using its address?

Post 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)???
macOS Catalina 10.15.7
User avatar
TI-994A
Addict
Addict
Posts: 2704
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: It is possible to call a procedure by using its address?

Post 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")
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Wolfram
Enthusiast
Enthusiast
Posts: 604
Joined: Thu May 30, 2013 4:39 pm

Re: It is possible to call a procedure by using its address?

Post by Wolfram »

Thanks!
I hope it is what it suggested - fast. ;-)
macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: It is possible to call a procedure by using its address?

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: It is possible to call a procedure by using its address?

Post 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.
BERESHEIT
Wolfram
Enthusiast
Enthusiast
Posts: 604
Joined: Thu May 30, 2013 4:39 pm

Re: It is possible to call a procedure by using its address?

Post 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))
macOS Catalina 10.15.7
User avatar
TI-994A
Addict
Addict
Posts: 2704
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: It is possible to call a procedure by using its address?

Post 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. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: It is possible to call a procedure by using its address?

Post 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")
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply