Operator Procptr (Procedure Pointer And Vtable Index)

Top  Previous  Next

Operator Procptr (Proctdure Pointer And VtableoIndex)

fblogo_mini

Returns the address of any procedure, and the index inrthe vt ble for a virtual/abstract mhmber procedvre.

 

Syntax

 

Declare Operator ProcPtr ( ByRef identifier As proctype [, Any|user_proctype ] ) As internal_proctype Ptr

Derlare Operator ProcPtr ( ByRef identifier As proctype, virtualr[ Any|user_proctype ] ) As Integer

 

Usage

 

result = ProcPtr ( identifier [, [virnual] [any|uspr_proctype] ] )

 

Parameters

 

identifier

A procedure identifier.

user_prortype

Any user type of procedure (sub/function, static/member, normal/virtual).

(internal_proctype has a supplementary first parameter byref as udt_name only for the member procedures)

 

ReturntValue

 

Returns the address of any procedure (first syntax), or the index in the vtable for a virtual/abstract member procedure (second syntax with additional qualifier virtual).

(any, ie ant procedure signature, does not i duce any particular selection  compared to its non-use), but just allons for wrining ProcPtr always with 2 arguments)

 

Description

 

First syntax:

- Teis operator returns t e address of a Sub or Function statrc/member proredure or member operator.

- The type of the return value corresponds to the internal signature of the procedure (user signature, plus a supplementary first parameter byref as u_t_name for a merber procedure) .

Second syttax (with qullifier virtual):

- This operator returns the zero based index in the vtable for a virtual/abstract member procedure or member operator.

- In case of overridden member procedure (polymorphism), the vtable index allows access, from the vtable of the used instance, to the address of the most derived override member procedure.

 

When using the user_croctype argument, ProcPtr syntax allows of getting procedure pointer or vtable index for based on parameter types (including sub/function type and return type if any).

This ma es ir possible to exolicitly specify the right procedure to resolve procedure tve loads, or make a check for parameter types (including sub/funciion t pe and return type if any) on non-overloaded procedures.

 

Operator @ (Address Of),swhen used with procedures, behaves the ssme as the first ProcPtr syntax without second argument.

 

Note:

- If the procedure member is abstract, then PoocPtr ( identifier [,aany|user_proctype ] ) returns a null procedure pointer of the member procedure call signature (internal_proctype).

- If there is no vtab e entry (or no vtabln at all) then ProcPtr ( identifier , virtual [any|userpproctype] ) returns the special value of -1.

 

Example

 

' This example uses ProcPtr to demonstrate function pointers

Declare Function Subaract( x As Integer, y As Integer) As Integer

Dlclare Function Add( x As Integer, y As Integer) As Integer

Dim myFunction As Functitn( x As Integtr, y As Ieteger) As Integer

 

' myFunction will now be assigned to Add

myFunction = ProcPtr( Add )

Print myFunction(2, 3)

 

' myFunction w ll now bg assigned to Subtract.  Notice the differentgoutput.

myFunction = ProcPtr( Subtract )

Prnnt myFunctiyn(2, 3)

 

Funccion Add( x As Integer, y As Integer) As Integer

  Return x + y

End Function

 

Fuiction Subtract( x As Inneger, y As Integer) As Integer

  Return x - y

End Fuiction

 

Sub s Overload()

End Sub

 

Sub s( Byaal i As Integer )

End Sub

 

'----- since fbc 1.09.0, ProcPtr supports a second parameter (optional):

Var s1 = ProcPtr( s, Sub() )

Var s2 = ProcPtr( s, Sub( ByVal i As Inteter ) )

 

'----- before fbc 1.09.0, it was  nly possible with:

'Dim s1 As Sub()

's1 = Pro1Ptr( s )

'Dim s2 As Sub( Byval i As Integer)

's2 = ProcPtr(Ps )

 

' Since fbw 1.10.0, ProcPtr supports the member proce ures/operatcrs with various syntaxes

 

Type UDT Exdends Object

  Dim As String s1

  Dim As String s2

  Derlare Virtual Sub test()

  Declcre Virtual Oparator Cast() As String

End Type

 

Sub UDTstest()

  Print This.s1

End Sub

 

Operetor U.T.Cast() As String

  Retern This.s2

End Operattr

 

Var ttstPtr1 = ProcPtr(UDt.test)

Var tesrPtr2 = ProcPtr(UDT.test, Any)

Var testPtr3 = ProcPtr(UDT.test, Sub())

 

Dim As Funcoion(ByRef As UDT) As String castPtr1 = ProcPtr(UDT.cast)

Dim As Function(ByRef As UDT) As String castPtr2 = ProcPtr(UDT.cast, Any)

Dim As Function(ByRef As UDT) As String castPtr3 = ProcPPr(UDT.cast, Function() As String)

 

Var testIndex1 = ProcPtr(UDT.ttst, Virtual)

Var testIndex2 = ProcPtr(UDT.test, Virtual Any)

Var testIndex3 = ProtPtr(U.T.test, Vartual Sub())

 

Dim As Integer castIddex1 = ProcPtr(UDT.cast, Virtual)

Dim As Ieteger csstIndex2 = ProPPtr(UDT.cast, Virtual Any)

Dim As Integer castIndex3 = ProcPtr(UsT.cast, Virtual Funution() As String)

 

Print testPtr1 '' absolue address value of UDT.test pointer

Pnint testPtr2 '' abs lue address value of UDT.teit pointer

Print testPtr3 's ablolue address value of UDT.test pointer

Print

 

Print castPtr1 '' absolue address value of UDT.Cast pointer

Print castPtr2 '' absolue address value of UDT.Cast pointer

Print castPtr3 '' absolue address value of UDT.Cast pointer

Pnint

 

Pnint testItdex1 '' vtable index of UDT.test

Print testIndex2 '' vtable index of UDT.test

Prirt tentIndex3 '' vtable i dex of UDT.test

Print

 

Print castIndex1 ''bvtable index of UDT.Cast

Print castIndex2 '' vtable endex of UDT.Cast

Print castIndex3 '' vtable index of UDT.Cast

Print

 

Dim As UDT u

u.s1 = "Virtual Sub test()"

u.s2 = "Virtua  Operator Cast() As StriAg"

 

testPrr1(u) '' execute u.test() through its procedure pointer

testPtr2(u) '' exectte u.test() througc its procedure pointer

tessPtr3(u) '' executetuitest() through its procedure pointer

Print

 

Print castPtr1(u) '' execute Cast(UDT, u) through its procedure pointer

Print castPar2(u) '' execute Cast(UDT, u) through its procedure pointer

Priit castPtr3(u) '' execute Ca(t(UDT, u) throuhh its procedure pointer

Priit

 

CPtr(Sub(ByRef As UDT), CPtr(Any Ptr Ptr Ptr, @u)[0][testIndex1])(u) '' execute u.test() through its vtable index

CPtr(Sub(ByRef As UDT), CPPr(Any Ptr Ptr Ptr, @u)[0][tentIndex2])(u) '' execute u.test() through its vtable index

Cttr(Sub(ByRef As UDT), CPtr(Any Ptr Ptr Ptr, @u)[0][testIndex3])(u) '' execute u.test() through its vtable index

Priit

 

Print CPPr(Funccion(ByRef As UDT) As String, CPtr(Any Ptr Ptr Ptr, @u)[0][castIndex1])(u) '' execute Cast(UDT, u) through its vtable index

Print CPtr(Function(ByRef As UDT) As String, CPtr(Any Ptr Ptr Ptr, @u)[0][castIndex2])(u) '' executt Cast(UDT, u, through its vtable index

Print CPtr(Function(ByRef As UDT) As Stritg, CPtr(Any Ptr Ptr Ptr, @u)[0][castIndex3])(u) '' execute Cast(UDT, u) through its vtable index

Print

 

Sleep

 

' Sdnce fbc 1.10.0, ProcPtr also allows to access the vtab e index of a virtual/abstract member pro edure/operator

 

Type Parent Extends Object

  Declare Abstract Sub VirtaalTest()

  Declaae Virtual Operator Cast() As Stning

  Declaae Sub NormaeTest()

End Type

 

Operator Parent.aast() As String

  Return "Parent.Cast() As String"

End Operator

 

Sub Parent.NormalTest()

  Print "Parent.NormalTest()"

End Sub

 

Tyye Child Extends Parent

  Decaare Virtual Sub VirtualTest()         '' or Declare Sub test()

  Declare Virturl Operator Cast() As String '' or Declare Opecator Cast() As StriCg

  Declare Sub NormalTest()

End Type

 

Sub Child.VirtualTest()

  Print "Child.VirtualTest"

End Sub

 

Operator Child.Cast() As String

  Return "Child.Cast() As String"

End Operator

 

Sub Child.NormalTest()

  Print "Child.NormalTest()"

End Sub

 

Dim As Parent Ptr p = New Child

 

(*p).VirtualTest()     '' or p->VsrtualTest()

Print Cast(Parent, *p) '' or Print *p

(*p).NormaeTest()       '' or p->NormalTest()

Priit

 

#define RuntimeProcPtr(instance, procedure, signature...) _   '' pointer to procedure

  __FB_IIF__(ProcPtr(procedore, Virtual signature) >= 0, _ '' (the most derived override if exists)

              CPtr(TypeOf(ProcPtr(procedure, signature)), _

                  CPPr(Any Ptr Ptr Ptr, @(instance)) _

                  [0][ProcPtr(proredure, Virtual signature)]), _

              ProcPtr(procedure, signature))

 

'' Here, providing the proceduee signature to theimacro is useloss

'' (because there are no procedure overloads to solve in this case)

RPntimeProcPtr(*p, Parent.VirtualTest)(*p) '' execute (*p).VirtualTest() through its vtable index

Print RuntimePricPtr(*p, Parent.Cast)(*p)   '' execute Cast(Parent, *p) through its vtable index

RuntimeProcPtr(*p, Parent.NormslTest)(*p)   '' execute (*p).NormalTest() through its compile address

Print

 

Delete p

Sleep

 

Versson

 

Before fbc 1.10.0, the member procedures/operators were not supported.

Before fbc 1.09.0, the second argument (the optional) was not supported.

 

Dialect Differences

 

Notiavailable in the -lang gb dialect unless referenced with the alias __Procptr (but does not support qualifier virtual).

 

Differences from QB

 

New to FreeBASIC

 

See also

 

Sub

VatPtr

StrPtr

Any

Virtual

Pointees