|
-
Oct 5th, 2024, 05:49 AM
#1
Another huge game changer feature: Delegate function pointer types (Call by pointer)
Thought this feature was also worth flagging for those who don't follow tB GitHub or Discord.
twinBASIC now supports Call By Pointer, by way of Delegates, which are function pointer types.
Code:
Private Delegate Function Delegate1 (ByVal A As Long, ByVal B As Long) As Long
Private Sub Command1_Click()
Dim myDelegate As Delegate1 = AddressOf Addition
MsgBox "Answer: " & myDelegate(5, 6)
End Sub
Public Function Addition(ByVal A As Long, ByVal B As Long) As Long
Return A + B
End Function
You can of course also use a LongPtr variable to assign to the delegate type.
The delegate type can also be used in interface/API declarations and as members of a User-defined type, for example, the ChooseColor API:
Code:
Public Delegate Function CCHookProc (ByVal hwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Public Type CHOOSECOLOR
lStructSize As Long
hwndOwner As LongPtr
hInstance As LongPtr
rgbResult As Long
lpCustColors As LongPtr
Flags As ChooseColorFlags
lCustData As LongPtr
lpfnHook As CCHookProc 'Delegate function pointer type instead of LongPtr
lpTemplateName As LongPtr
End Type
If you already have code assigning a Long/LongPtr to the lpfnHook member, it will continue to work normally, but now you can also have the type safety benefits of setting it to a method matching the Delegate:
Code:
Dim tCC As CHOOSECOLOR
tCC.lpfnHook = AddressOf ChooseColorHookProc
...
Public Function ChooseColorHookProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
End Function
A much, much better way of implementing call by pointer compared to the standard ways of DispCallFunc or asm thunks!
-
May 22nd, 2025, 09:23 PM
#2
Re: Another huge game changer feature: Delegate function pointer types (Call by point
That is a massive step for a VB6 clone! Huge.
How close are you guys to being able to write things like this in tB?
Code:
Public Class Form1
Private Delegate Function FilterPredicate(Of T)(ByVal item As T)
Private Function Filter(Of T)(ByVal items As T(), ByVal filterPred As FilterPredicate(Of T)) As T()
Dim newList As New List(Of T)
For Each item In items
If filterPred(item) Then newList.Add(item)
Next
Return newList.ToArray()
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim names = {"John", "Smith", "Kane", "Tessa", "Yoland", "Royce", "Samuel"}
'Filter out names that start with "s"
Dim filterNames = Filter(names, Function(n) n.ToLower.StartsWith("s"))
Stop
End Sub
End Class
I'm referring specifically to the Filter function and everything that supports it like generic functions, anonymous functions and of course delegates which you already have.
Last edited by Niya; May 22nd, 2025 at 09:27 PM.
-
May 23rd, 2025, 12:07 AM
#3
Re: Another huge game changer feature: Delegate function pointer types (Call by point
tB has some support for generics in sub/function and classes, but doesn't support them with delegates yet. Or whatever the heck that 2nd argument at the Filter callsite.
I started seeing how close I could get and I'll come back to it later, for now here's some generics examples working right now.
Code:
Module testmod
Private Sub testc()
Dim names As List(Of String) = New List(Of String)(Array("John", "Smith", "Kane", "Tessa", "Yoland", "Royce", "Samuel"))
Dim s As String = names(0)
Debug.Print s
End Sub
End Module
[COMCreatable(False)]
Class List(Of T)
Private src() As T
Private c As Long
Sub New(p() As T)
For i As Long = 0 To UBound(p)
ReDim Preserve src(c)
src(c) = p(i)
c += 1
Next
End Sub
[DefaultMember]
Function GetAt(ByVal idx As Long) As T
Return src(idx)
End Function
Public Property Get Count() As Long
Return c
End Property
End Class
Code:
Public Function GetMem(Of T)(ByVal ptr As LongPtr) As T
vbaCopyBytes(LenB(Of T), VarPtr(GetMem), ptr)
End Function
Public Function DCast(Of T, T2)(ByVal v As T2) As T
If LenB(Of T2) >= LenB(Of T) Then
vbaCopyBytes(LenB(Of T), VarPtr(DCast), VarPtr(v))
Else
vbaCopyBytes(LenB(Of T2), VarPtr(DCast), VarPtr(v))
End If
End Function
Last edited by fafalone; May 23rd, 2025 at 12:33 AM.
-
May 23rd, 2025, 02:16 AM
#4
Re: Another huge game changer feature: Delegate function pointer types (Call by point
Wow. tB has come a long way.
 Originally Posted by fafalone
Or whatever the heck that 2nd argument at the Filter callsite.
You referring to this?
Code:
Dim filterNames = Filter(names, Function(n) n.ToLower.StartsWith("s"))
You guys probably don't have that yet in tB. Filter is what is called a higher order function. It takes a function as a parameter, delegates are kind of a prerequisite for them, at least in manner presented here. The second parameter defines what is called an anonymous function. In this case, Filter cycles through the items from the array passed into the first parameter and calls that anonymous function on each of them to determine whether they start with "s" or not.
The idea here is that you can define a single filtering function that can have wildly different filtering conditions defined at the callsite. Delegates are what make this possible in .Net.
-
May 23rd, 2025, 06:52 AM
#5
Re: Another huge game changer feature: Delegate function pointer types (Call by point
This is very good. Hopefully examples like these can make their way into the documentation for TB (if not already present)
The idea of delegates as described above is very informative for many of us that haven't used them before. An example as to why we would want to use them is also very useful. More of those required.
Niya's example is also useful demonstrating the use of a delegate upon which the anonymous function performs its wizardry. I have used anonymous functions before in TypeScript and they are compact and I don't want to say the word again but, useful.
https://github.com/yereverluvinunclebert
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
-
May 23rd, 2025, 07:44 AM
#6
Re: Another huge game changer feature: Delegate function pointer types (Call by point
The New Features wiki page already had examples for delegates and generics; I added the Class generic example when I wrote it yesterday.
-
May 23rd, 2025, 07:56 AM
#7
Re: Another huge game changer feature: Delegate function pointer types (Call by point
https://github.com/yereverluvinunclebert
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
-
May 27th, 2025, 08:11 PM
#8
Fanatic Member
Re: Another huge game changer feature: Delegate function pointer types (Call by point
Having a background only in VB, I'm not clear on what Delegates or they're usefulness. Anyone care to enlighten me? When would I need this?
-
May 28th, 2025, 05:41 AM
#9
Re: Another huge game changer feature: Delegate function pointer types (Call by point
It's primarily for when you only have a pointer to a function and want to call that function. As an example, in an Excel XLL addin, the only practical way to find the function your addin has to call it to use GetProcAddress(GetModuleHandleW(0), "MdCallback12")-- there's no separate DLL for a regular declare. That just gives you an address, so how do you call it? In VB6, you need to use a big, painful, and slow DispCallFunc routine or inline assembly. In tB,
Code:
Private Const EXCEL12ENTRYPT = "MdCallBack12"
Private Delegate Function EXCEL12PROC (ByVal xlfn As ExcelCommandNumbers, ByVal coper As Long, rgpxloper12 As LongPtr, xloper12Res As XLOPER12) As Long
Private pexcel12 As EXCEL12PROC
pexcel12 = CType(Of EXCEL12PROC)(GetProcAddress(GetModuleHandleW(0), EXCEL12ENTRYPT))
Now pexcel12 is used like any other function... Dim result As Long = pexcel12(123, 4, ...) . The arguments will come up in Intellisense.
The other use is type safety in callbacks. For APIs that use callback functions, typing it as a delegate tells you what the definition should look like and makes sure it matches up. I.e. for a TimerProc for SetTimer, with delegates it's not just some random LongPtr you have to look to outside docs to see how it's set up with no help from the compiler,
Code:
Public Delegate Sub TIMERPROC (ByVal hWnd As LongPtr, ByVal uMsg As Long, ByVal TimerID As LongPtr, ByVal Tick As Long)
Public Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As TIMERPROC) As LongPtr
Sub test()
SetTimer 0, 0, 0, AddressOf BadProc
End Sub
Function BadProc(OnlyOne As Long) As Byte
End Function
Sub GoodProc(ByVal hWnd As LongPtr, ByVal uMsg As Long, ByVal TimerID As LongPtr, ByVal Tick As Long)
End Sub
You'll see here you get a warning that it's mismatched. Changing it to GoodProc, the warning goes away.
(Note: WinDevLib currently doesn't use delegates in API defs due to a bug relating to delegates in packages, but you could do Dim lpProc As TIMERPROC = AddressOf BadProc/GoodProc): SetTimer 0, 0, 0, lpProc
Last edited by fafalone; May 28th, 2025 at 05:44 AM.
-
May 29th, 2025, 04:04 AM
#10
Re: Another huge game changer feature: Delegate function pointer types (Call by point
 Originally Posted by AAraya
Having a background only in VB, I'm not clear on what Delegates or they're usefulness. Anyone care to enlighten me? When would I need this?
In addition to what faf said, here's a simple way to conceptualize it. It's a "type safe function pointer".
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|