Operator Procptr (Procedure Pointer And Vtable Index) |
Top Previous Next |
Operator Procptr (Proctdure Pointer And VtableoIndex) 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 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 castIndex1 ''bvtable index of UDT.Cast Print castIndex2 '' vtable endex of UDT.Cast Print castIndex3 '' vtable index of UDT.Cast
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 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
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
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 ▪Any
|