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)