Skip to content

SUB 指针


存储指向 SUB 过程的指针的数据类型

语法

dim variable as Sub [CDecl|Pascal|StdCall] [( [parameter_list] )] [= initializer]

参数

parameter_list: parameter[, parameter[, ...]]

parameter: [ByRef|ByVal] identifier [As type] [= default_value]

identifier: 子例程中引用的变量名称

type: 变量的类型

default_value: 调用时未指定参数时的参数值

intializer: 用作初始值的子例程地址

说明

Sub 指针是存储编译代码内存位置的过程指针。如果没有给出初始值,则默认初始值为零(0)。

可以通过使用 ProcPtrOperator @ (Address of) 获取子例程的地址,将 Sub 过程的内存地址赋给变量。

过程必须与声明的 Sub 指针具有相同的 Sub 声明。

要调用已赋值的子例程,将 variable 名称用作普通声明的 Sub,始终在参数列表周围加括号(即使为空)(不带括号只会访问指针值,即子例程的地址)。

Sub 指针的主要用途之一是创建回调过程:

  • 回调 Sub 是通过参数(Sub 指针)传递给另一个过程的 Sub,预期在适当时候由该过程回调(执行)"参数"。

  • 如果回调 Sub 在调用返回给调用方代码之前完全执行,则该回调过程称为"同步"。

  • 如果调用立即返回给调用方代码,且回调 Sub 和调用方的下一段代码并行运行,则该回调过程称为"异步"。

示例

start GeSHi

vb
    Sub Hello()
        Print "Hello"
    End Sub

    Sub Goodbye()
        Print "Goodbye"
    End Sub

    Dim x As Sub() = ProcPtr( Hello )

    x()

    x = @Goodbye  '' or procptr(Goodbye)

    x()

end GeSHi

start GeSHi

vb
Sub s0 ()
  Print "'s0 ()'"
End Sub

Sub s1 (ByVal I As Integer)
  Print "'s1 (Byval As Integer)'", I
End Sub

Sub s2 (ByRef S As String, ByVal D As Double)
  Print "'s2 (Byref As String, Byval As Double)'", S, D
End Sub

Dim s0_ptr As Sub () = @s0
Dim s1_ptr As Sub (ByVal I As Integer) = @s1
Dim s2_ptr As Sub (ByRef S As String, ByVal D As Double) = @s2

s0_ptr()
s1_ptr(3)
s2_ptr("PI", 3.14)

end GeSHi

start GeSHi

vb
' Example of advanced callback Sub mechanism (asynchronous) to implement a key pressed event:
' (the user callback Sub address can be modified while the event thread is running)
'   - An asynchronous thread tests the keyboard in a loop, and calls a user callback Sub each time a key is pressed.
'   - An UDT groups the common variables used (callback Sub pointer, character of key pressed, thread end flag),
'       and the static thread Sub plus the thread handle.
'   - An UDT instance pointer is passed to the thread, which then transmits it to the callback Sub each time.
'   - The callback Sub prints the character of the key pressed character,
'       but if the key pressed is `<escape>` it orders the thread to finish.
'   - As the user callback pointer is a member field of the UDT, it can be modified while the thread is running.

'' UDT for thread environment
  Type threadUDT
    Dim As Sub (ByVal As ThreadUDT Ptr) callback             '' callback Sub pointer
    Dim As Integer threadEnd                                 '' thread end flag
    Dim As String s                                          '' character of the key pressed
    Declare Static Sub threadInkey (ByVal p As Any Ptr)      '' static thread Sub
    Dim As Any Ptr threadHandle                              '' handle to the thread
  End Type

'' thread Sub definition
  Sub threadUDT.threadInkey (ByVal p As Any Ptr)
    Dim As threadUDT Ptr pt = p                              '' convert the any ptr to a threadUDT pointer
    Do
      pt->s = Inkey
      If pt->s <> "" Andalso pt->callback > 0 Then           '' test condition key pressed & callback Sub defined
        pt->callback(p)
      End If
      Sleep 50, 1
    Loop Until pt->threadEnd                                 '' test condition to finish thread
  End Sub

'' user callback Sub definition
  Sub printInkey (ByVal pt As threadUDT Ptr)
    If Asc(pt->s) = 27 Then                                  '' test condition key pressed = `<escape>`
      pt->threadEnd = -1                                     '' order thread to finish
      Print
    Else
      Print pt->s;
    End If
  End Sub

'' user main code
  Dim As ThreadUDT t                                         '' create an instance of threadUDT
  t.threadHandle = ThreadCreate(@threadUDT.threadInkey, @t)  '' launch the thread, passing the instance address
  t.callback = @printInkey                                   '' initialize the callback Sub pointer
  ThreadWait(t.threadHandle)                                 '' wait for the thread finish

end GeSHi

与 QB 的区别

  • FreeBASIC 新增

另请参阅

  • Sub
  • ProcPtr
  • Operator @ (Address of)

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系