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

FreeBASIC ProPgCallback

目次→教本→プログラマーのための案内Callback←オリジナル・サイト

呼び戻し 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

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

コールバック手続き

記述:
出典: フリー百科事典『ウィキペディア(Wikipedia)』
コールバック(英: Callback)とは、プログラミングにおいて、他のコードの引数として渡されるサブルーチンである。これにより、低レベルの抽象化層が高レベルの層で定義されたサブルーチン(または関数)を呼び出せるようになる。
一般に、まず高レベルのコードが低レベルのコードにある関数を呼び出すときに、別の関数へのポインタやハンドルを渡す。低レベルの関数を実行中に、その渡された関数を適当な回数呼び出して、部分タスクを実行する場合もある。別の方式では、低レベル関数は渡された関数を「ハンドラ」として登録し、低レベルの層で非同期的に(何らかの反応の一部として)後で呼び出すのに使う。

例:
数学関数(一次・二次関数、正弦関数)が、描画関数(PlotF)の引数となる例:
(呼び出しは 'PlotF()' 手続きを呼び出すことによって実装され、コールバック関数は 'Linear()', 'Sinusoidal()', 又は 'Quadratic()' 関数です)

Type MathFunction As Function( ByVal x As Double ) As Double

Function Linear( ByVal x As Double ) As Double
    Return x
End Function

Function Quadratic( ByVal x As Double ) As Double
    Return x * x
End Function

Function Sinusoidal( ByVal x As Double ) As Double
    Return Sin(x)
End Function

Sub PlotF( ByVal f As MathFunction )
    PSet( -15, f(-15) )
    For x As Double = -15 To 15 Step 0.1
        Line -( x, f(x) )
    Next
End Sub

' Sets the graphics method GDI
' 描画方法を GDI に設定
SetEnviron("fbgfx=GDI")

Screen 19
Window (-15,-10)-(15,10)

PlotF( @Linear )
PlotF( @Sinusoidal )
PlotF( @Quadratic )

Sleep

注:FreeBASIC 1.08〜 で、SetEnviron を追加しなくても、日本語環境で描画画面が表示されるように改善されました。
3つのコールバック処理は同期的です。
'PlotF()' が呼び出し元のコードに戻る前に、各コールバック関数が完全に実行されるためです。

同様の描画例(上と同様)ですが、非同期コールバックを使います。
ここでは、人為的な遅延を加えています。
より現実的なケースは、描画されるデータが、プログラムのメインループで許容できるよりも長い応答時間で Webサーバーから取得される場合です(ブロッキング動作を防止します):
#Include "fbthread.bi"

Type MathFunction As Function( ByVal x As Double ) As Double

Sub ThreadPlot( ByVal p As Any Ptr )
    Sleep 1500, 1  '' sleep added only to check the asynchronous way of the callback
    Dim f As MathFunction = p
    Window (-15,-10)-(15,10)
    PSet( -15, f(-15) )
    For x As Double = -15 To 15 Step 0.1
        Line -( x, f(x) )
    Next
End Sub

Function PlotF( ByVal f As MathFunction ) As String
    Print "Plotting requested"
    Threaddetach( ThreadCreate( @ThreadPlot, f ) )
    Return "Plotting request taken into account"
End Function

Function Linear( ByVal x As Double ) As Double
    Return x
End Function

Function Quadratic( ByVal x As Double ) As Double
    Return x * x
End Function

Function Sinusoidal( ByVal x As Double ) As Double
    Return Sin(x)
End Function

' Sets the graphics method GDI
' 描画方法を GDI に設定
SetEnviron("fbgfx=GDI")

Screen 19

Print PlotF( @Linear )
Print PlotF( @Sinusoidal )
Print PlotF( @Quadratic )

'' 以下のコードは呼び戻しの非同期性をチェックするためだけに追加
Print "Main program continues ";
For I As Integer = 1 To 15
    Print ".";
    Sleep 200, 1
Next I
Print
Print "Main program finished"

Sleep

3つのコールバック処理は、非同期です。
これは、'PlotF()' 関数がすぐに戻り、それぞれのコールバック関数が 'PlotF()' によって(以前に)作成された 'ThreadPlot()' スレッドから、呼び出し元の次のコードと並行して実行されるからです。

qsort アルゴリズムでソートされる配列の値を比較する呼び戻し関数の例:
(呼び出しは 'qsort()' 手続きを呼び出すことによって実装され、コールバック関数は 'CmpVarLenStr()' 関数です)
#include "crt/stdlib.bi"

Function CmpVarLenStr CDecl( ByVal p1 As Any Ptr, ByVal p2 As Any Ptr ) As Long  '' compare 2 var-len strings
    Dim As String Ptr ps1 = p1
    Dim As String Ptr ps2 = p2
    If *ps1 < *ps2 Then
        Return -1
    ElseIf *ps1 > *ps2 Then
        Return 1
    Else
        Return 0
    End If
End Function

Sub PrintList( array() As String)  '' print a var-len string list
    For I As Integer = LBound(array) To UBound(array)
        Print array(I)
    Next I
    Print
End Sub

Dim forename(1 To 12) As String = {"Madison", "Emily", "Hailey", "Sarah", "Kaitlyn", "Hannah", _
                                   "Jacob", "Christopher", "Nicholas", "Michael", "Matthew", "Joshua" }

Print "LIST OF UNSORTED FORENAMES:"
PrintList( forename() )

qsort( @forename(LBound(forename)), UBound(forename) - LBound(forename) + 1, SizeOf(String), @CmpVarLenStr )

Print "LIST OF SORTED FORENAMES:"
PrintList( forename() )

Sleep

コールバック関数は完全に(数回)実行され、'qsort()' が呼び出し元のコードに戻る前に 'qsort()' によって(連続して)呼び出されるため、コールバックプロセスは同期的です。

参照:
プログラマーのための案内に戻る
目次に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2021-07-08 11:00:49
日本語翻訳:WATANABE Makoto、原文著作者:badidea

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

表示-非営利-継承