增强的指针功能
twinBASIC 为处理指针提供了几个增强功能。
ByVal Nothing
此外,虽然不是严格的新语法,twinBASIC 还添加了对ByVal Nothing的支持,以覆盖ByRef <接口>参数并在那里传递空指针。
vbNullPtr
允许向 API/接口的 UDT 成员传递空指针。在 VBx 中的等效行为是将它们声明为As Any,然后在调用点传递ByVal 0。
示例
vb
Type Foo
bar As Long
End Type
Public Declare PtrSafe Function MyFunc Lib "MyDLL" (pFoo As Foo) As Long
Private Sub CallMyFunc()
Dim ret As Long = MyFunc(vbNullPtr)
End SubCType(Of <类型>)
CType(Of <类型>)操作符指定将一种类型显式转换到另一种类型的意图。这可以用于将LongPtr(或在 32 位上的Long/在 64 位上的LongLong)转换为用户自定义类型,根据使用情况复制或不复制它。这不仅允许直接转换而无需调用CopyMemory,还允许设置仅由指针表示的 UDT 的成员,而无需来回复制内存。
示例
考虑以下 UDT:
vb
Private Type foo
a As Long
b As Long
pfizz As LongPtr '指向 fizz 类型变量的指针
End Type
Private Type bar
pfoo As LongPtr '指向 foo 类型变量的指针
End Type
Private Type fizz
c As Long
End Type以下代码示例可以操作指针:
vb
Sub call1()
Dim f As foo
test1 VarPtr(f)
Debug.Print f.a, f.b
End Sub
Sub test1(ByVal ptr As LongPtr)
With CType(Of foo)(ptr)
.a = 1
.b = 2
End With
End Sub这将打印1 2。
vb
Sub call2()
Dim f As foo, b As bar
b.pfoo = VarPtr(f)
test2 b
Debug.Print f.a, f.b
End Sub
Sub test2(b As bar)
With CType(Of foo)(b.pfoo)
.a = 3
.b = 4
End With
End Sub这将打印3 4。
vb
Sub call3()
Dim f As foo, b As bar, z As fizz
f.pfizz = VarPtr(z)
b.pfoo = VarPtr(f)
test3 b
Debug.Print z.c
End Sub
Sub test3(b As bar)
CType(Of fizz)(CType(Of foo)(b.pfoo).pfizz).c = 4
End Sub这将打印4。也允许独立使用和嵌套;上述将打印4。虽然这里的示例仅是本地代码,但这对于 API 特别有用,在那里您被迫广泛使用指针。
用指针替换 UDT
在 API 和本地方法中,任何接受用户定义类型的参数都可以改为传递ByVal LongPtr,使用新的特殊常量vbNullPtr表示空指针:
vb
Public Declare PtrSafe Function CreateFileW Lib "kernel32" (ByVal lpFileName As LongPtr, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As LongPtr) As LongPtr
hFile = CreateFileW(StrPtr("名称"), 0, 0, ByVal vbNullPtr, '...)
'---或---
Dim pSec As SECURITY_ATTRIBUTES
Dim lPtr As LongPtr = VarPtr(pSec)
hFile = CreateFileW(StrPtr("名称"), 0, 0, ByVal lPtr, '...)Len/LenB(Of <类型>) 支持
传统的Len和LenB函数现在可以用于直接获取类型的长度/大小,包括内置类型和用户定义类型,而无需声明该类型的变量。例如,要知道指针大小,您可以使用LenB(Of LongPtr)。
AddressOf 的改进
AddressOf现在可以用于类/窗体/用户控件成员,包括通过指定实例从类外部使用。此外,不再需要FARPROC类型的函数,您可以像Ptr = AddressOf Func一样使用它。因此,如果您有带有成员函数bar的类CFoo,以下代码是有效的:
vb
Dim foo1 As New CFoo
Dim lpfn As LongPtr = AddressOf foo1.bar