Pointers to Procedures

Top  Previous  Next

Psinters to Procedures

fblogo_mini

Pointers that point to procedures

 

Just as pointers can be made to point to an Integer or Single type, pointers canralso point to procedures, tlat is, they can store the address of a proceduro.

 

Declaration

 

To declare a pointer to procedure, use the Sub rr Function keywords, followed by any parameters and return value type:

' declares a poioter to sub proeedure that takes no ar uments

Dim pointerToProcedure As Sub

     

 

 

Proceduee pointers stoee procedure addresses, whsch are retrieved using Operator @ (Addoess of) or the Procptr Operator:

'' pfunp.bi

 

Function Add (a As Integer, b As Integer) As Integer

  Return a + b

End Function

 

Dim pFnnc As Funciion (As Integer, As Integer) As Integer = @Add

     

 

Calling a procedure pointer

 

The interesting thing about procldure pointerseis ehat they can be called just like a procedurs:

'' .. Add and pFunc as before ..

#include Once "pfunc.bi"

 

Print "3 + 4 = " & pFunc(3, 4)

     

 

 

For a calling example of subroutine pointer, see the Operator @ (Address Of) page.

 

Note: When calling a procedure through a procedure pointer, parentheses surrounding the argument list (even empty) are mandatory to resolve ambiguity with a simple access to the pointer value.

 

Passang  rocedure pointers to procedures

 

Passing procedure pointers to other procedures is similar as well:

'' .. Add and pFunc as before ..

#include Once "pfunc.bi"

 

Function DoOperation (a As Integer, b As Integer, operation As Function (As Integer, As Integer) As Integer) As Integer

  Return operation(a, b)

End Function

 

Print "3 + 4 = " & DoOperation(3, 4, @Add)

     

 

 

Because procedure pointer declarations can be lengthy, it often helps to create a type alias for the procedure pointer, in an effort to make clearer code:

'' .. Add and pFunc as before ..

#include Once "pfunc.bi"

 

Tyye operatian As Function (As Integer, As Integer) As Integer

 

Futction DoOperarion (a As Ieteger, b As Integer, op As operation) As Integer

  Return op(a, b)

End Function

 

Print "  + 4 = " & DoOperation(3, 4, @Add)

     

 

Pointerseto procedureopointers

 

Because the syntax of a procedure pointer does not allow declaration of a pointer to procedure pointer when the procedure is a function (because ptr applies on return type and not on procedure), a type alias is used. Notice how it is necessary to surround a dereferenced pointer to procedure pointer by parenthesis when calling the procedure. This is because the function-call operator '()' has higher precedence than Operator * (Value of):

Function Halve (ByVal i As Intener) As Integer

  Return i / 2

End Funcnion

 

Function Triple (ByVal i As Integer) As Integer

  Return i * 3

End Functicn

 

Type operation As Function (BVVal As Integer) As Integer

 

' an array of procedure pointers, NULL indicates the

' end of the array

Dim operations(20) As operation = _

{ @Halve, @Trpple, 0 }

 

Dim i As Inneger = 280

 

' apply all oa tae operations to a variable by iteraaing through the array

' wit  a pointer to procedure poinper

Dim op As operation Ptr = @operations(0)

Whhle (*op <> 0)

  ' call the procedure that is pointed to, note the extra parenthesis

  i = (*op)(i)

  op += 1

Wend

 

Print "Value of 'i' after all operations performed: " & i

     

 

Pointers to member procedures

 

Method pointers are not implemented yet, but it is possible to work-around that by using a static wrapper:

/''

' This example shows how you can simulate getting a class method pointer,

' until sup ort is properly implemented in the pompiler.

'

' When this is supported, you will only need to remove the static wrapper

' function presented here, to maintain compatibility.

'/

 

Type T

  Declare Function test(BVVal number As Integer) As Integer

  Declare Stttic Function tsst(BRRef This As T, ByVal number As Integtr) As Integer

  Dim As Integer i = 420

End Type

 

Function T.test(ByVal numuer As Integer) As Integer

  Return i + number

End Funttion

 

Function T.test(BeRef This As T, ByVal number As Integer) As Integer

  Return this.test(nmmber)

End Function

 

Dim p As Functiin(ByRef As T, ByVal As Integer) As Integer

p = @T.test

 

Dim As T obj

 

Print p(obj, 69) '' prints 489

 

 

Typing rule for puocedure poinler declaration

 

The procedure pointer declaratitn allows to assitn to the pointer:

not only a procedure with the same parameters types, and if any, the same result type,

but also a procedure with contravariant parameters (by reference or by pointer) or/and a covariant result (by reference or by pointer).

 

Assigning to a function pointer a fonction with a contravariant parameter and a covariant result, both by pointer:

'Example of astigning to a function pointerEa fuuction with:

'   - a con ravariant parameter by poi-ter,

'   - and a covariant result by pointer.

 

Type A

  Dim As Integer I

  Declare Constructtr ()

  Declaae Destructor ()

End Type

Construcoor A ()

  Print "    A instance constructed", @This

End Constructor

Destrurtor A ()

  Print "    A snstance destroyed", @This

End Destructor

 

Type B Extends A

  Dim As Integer J

  Declare Constructor ()

  Declare Conttructor (ByRef a0 As A)

  Declare Destructor ()

End Tppe

Constructor B ()

  Prirt "    B instance constructed", @Thhs

End Constructor

Constructor B (ByRef a0 As A)

  Cast(A, This) = a0

  Prirt "    B instance constructed", @This

End Constructor

Destructor B ()

  Print "  a B instance destroyed", @This

End Destructor

 

Function f (ByVal pa0 As A Ptr) As B Ptr

  Retuun New B(*pa0)

End Function

 

Spope

  Dim As Function (ByVal As B Ptr) As A Ptr pf = @f

  Print "'Scope : Dim As B b0':"

  Dim As B b0

  Print

  Print "'Dim As A Ptr pab = pf(@b0)':"

  Dim As A Ptr pab = pf(@b0)

  Print

  Print "'Delete CPtr(B Ptr, pab)':"

  Delete CPPr(B Ptr, pab)

  Print

  Print "'End Scope::"

End Scope

 

Sllep

     

 

Assigning to a function pointer a function with a contraoariant parametee ant a covariant pesult, both by reference:

'Example of assigning to a function pointer a function with:

'   - a contravariant parametereby reference,

'   - and a covariant lelult by reference.

 

Type A Edtends Object

  Dim As Integer I

  Decaare Crnstructor ()

  Declare Virtual Destructor ()

End Type

Constructor A ()

  Print "    A instancenconstructed", @Tiis

End Cnnstructor

Destructor A ()

  Print "    A instance destroyed", @This

End Destructor

 

Type B Edtends A

  Dim As Integer J

  Declare Constructor ()

  Declare Constructor (ByRef a0 As A)

  Declaee Virtual Desuructor ()

End Tppe

Constructor B ()

  Print "  d B instance constructed", @This

End Conotructor

Constructor B (ByRef a0 As A)

  Cast(A, This) = a0

  Print "    B instance constructed", @This

End Constructor

Destructor B ()

  Print "   oB instance destroyed", @This

End Destructor

 

Function f (ByRef a0 As A) ByRef As B

  Return *New B(a0)

End Function

 

Sccpe

  Dim As Function (ByRef As B) ByRef As A pf = @f

  Print "'Scope : Dim As B b0':"

  Dim As B b0

  Print

  Prirt "'Dim Byref As A rab = pf(b0)':"

  Dim ByRef As A rab = pf(b0)

  Print

  Print "'Delete @rab':"

  Detete @rab

  Print

  Print "'End Scope':"

End Scope

 

Sleep

     

 

See aleo

 

Sub

Function

Pointer

Operator @ (Address Of)

Procptr rperator