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

FreeBASIC ExtLibFfi

目次→その他→ライブラリ・ヘッダー索引libffi←オリジナル・サイト
目次→FreeBASIC のハッキング→FreeBASIC でのハッキングのための情報外部ライブラリ索引libffi←オリジナル・サイト

libffi


LibFFI は、あるプログラミング言語から他のプログラミング言語で定義された関数を利用するための、関数インターフェース・ライブラリです。
プログラムが、任意に、ポインターなしで、固有の関数を呼んで、関数閉包(クロージャ)経由で、変数の引数をとる、一般的な関数に、関数ポインターを結びつけられるようにします。
これは、現代のスクリプト言語で、固有のコードを結びつけるときに使います。

ウエブ・サイト: https://sourceware.org/libffi/
利用できる環境: Windows, Linux, DOS
include するヘッダー: ffi.bi
ヘッダー・バージョン: 3.1

例:
Hello world:
#include "ffi.bi"

' Simple "puts" equivalent function
Function printer cdecl (ByVal s As ZString Ptr) As Integer
    Print *s
    Return 42
End Function

' Initialize the argument info vectors
Dim s As ZString Ptr
Dim args(0 To 0) As ffi_type Ptr = {@ffi_type_pointer}
Dim values(0 To 0) As Any Ptr = {@s}

' Initialize the cif
Dim cif As ffi_cif
Dim result As ffi_status
result = ffi_prep_cif( _
    @cif,              _ ' call interface object
    FFI_DEFAULT_ABI,   _ ' binary interface type
    1,                 _ ' number of arguments
    @ffi_type_uint,    _ ' return type
    @args(0)           _ ' arguments
)

' Call function
Dim return_value As Integer
If result = FFI_OK Then
    s = @"Hello world"
    ffi_call(@cif, FFI_FN(@printer), @return_value, @values(0))

    ' values holds a pointer to the function's arg, so to
    ' call puts() again all we need to do is change the
    ' value of s */
    s = @"This is cool!"
    ffi_call(@cif, FFI_FN(@printer), @return_value, @values(0))
    Print Using "Function returned &"; return_value
End If


Closures:
#include "ffi.bi"

' Acts like puts with the file given at time of enclosure.
Sub Printer cdecl(ByVal cif As ffi_cif Ptr, ByVal ret As Any Ptr, ByVal args As Any Ptr Ptr, ByVal File As Any Ptr)
    Write #*CPtr(Integer Ptr, file), **CPtr(ZString Ptr Ptr, args[0])
    *CPtr(UInteger Ptr, ret) = 42
End Sub

' Allocate the closure and function binding
Dim PrinterBinding As Function(ByVal s As ZString Ptr) As Integer
Dim closure As ffi_closure Ptr
closure = ffi_closure_alloc(SizeOf(ffi_closure), @PrinterBinding)

If closure <> 0 Then
    ' Initialize the argument info vector
    Dim args(0 To 0) As ffi_type Ptr = {@ffi_type_pointer}
   
    ' Initialize the call interface
    Dim cif As ffi_cif
    Dim prep_result As ffi_status = ffi_prep_cif( _
        @cif,            _ ' call interface object
        FFI_DEFAULT_ABI, _ ' binary interface type
        1,               _ ' number of arguments
        @ffi_type_uint,  _ ' return type
        @args(0)         _ ' arguments
    )
    If prep_result = FFI_OK Then
        ' Open console file to send to PrinterBinding as user data
        Dim ConsoleFile As Integer = FreeFile()
        Open Cons For Output As ConsoleFile
       
        ' Initialize the closure, setting user data to the console file
        prep_result = ffi_prep_closure_loc( _
            closure,         _ ' closure object
            @cif,            _ ' call interface object
            @Printer,        _ ' actual closure function
            @ConsoleFile,    _ ' user data, our console file #
            PrinterBinding   _ ' pointer to binding
        )
        If prep_result = FFI_OK Then
            ' Call binding as a natural function call
            Dim Result As Integer
            Result = PrinterBinding("Hello World!")
            Print Using "Returned &"; Result
        End If
       
        Close ConsoleFile
    End If
End If

' Clean up
ffi_closure_free(closure)


外部ライブラリー目次に戻る

ページ歴史:2020-12-31 13:51:18
日本語翻訳:WATANABE Makoto、原文著作者:DkLwikki

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

表示-非営利-継承