FreeBASIC マニュアルのトップに戻る

FreeBASIC SubPtr

目次→言語リファレンス→変数とデータ型→標準のデータ型SUB Pointer←オリジナル・サイト

SUB Pointer(関数) 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

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)です。

Sub 手続きのメモリアドレスは、ProcPtr または Operator @ (Address of) を使用して、サブルーチンのアドレスを取得することによって、変数に割り当てることができます。

手続きは、宣言された Sub ポインタと、同じ Sub 宣言と一致しなければなりません。

割り当てられたサブルーチンを呼び出すには、通常の宣言された Sub のように variable 名を使用します。
常にパラメーターリストを括弧で囲み、空でもかまいません(括弧がない場合は、ポインター値、つまりサブルーチンのアドレスのみがアクセスされます)。

Sub ポインタの主な用途の 1つは、コールバック手続きを作成することです:
- コールバック Sub は、引数(Sub ポインタ)を介して他の手続きに渡される Sub で、都合のよいときに「引数」をコールバック(実行)できます。
- コールバック Sub が、呼び出しが、呼び出し元のコードに戻る前に完全に実行された場合、コールバック処理は「同期」と言われます。
- 呼び出しがすぐに呼び出し元のコードに戻り、コールバック Sub と呼び出し元の次のコードが並行して実行されている場合、コールバック処理は「非同期」と言われます。

例:
    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()


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)


' キー押下イベントを実装するための、高度なコールバック Sub メカニズムの例:
' (ユーザー・コールバックの Sub アドレスは、イベント・スレッドの実行中に変更することができます)
'   - 非同期スレッドはループ内でキーボードをテストし、キーが押されるたびにユーザーコールバック Sub を呼び出します。
'   - UDT は、使用される(コールバック Sub ポインタ、押されたキーの文字、スレッド終了フラグ)一般的な変数、
'       および静的スレッド Sub とスレッドハンドルを、グループ化します。
'   - UDT インスタンス・ポインタがスレッドに渡され、スレッドは毎回それをコールバック Sub に送信します。
'   - コールバック Sub は、押されたキーの文字を表示しますが、
'       押されたキーが <escape> の場合、スレッドに終了を指示します。
'   - ユーザー・コールバック・ポインタは UDT のメンバフィールドであるため、スレッドの実行中に変更することができます。


'' 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


QBからの違い: 参照:
標準のデータ型 に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2021-08-03 15:21:58
日本語翻訳:WATANABE Makoto、原文著作者:JeffMarshall

ホームページのトップに戻る

表示-非営利-継承