libffi
 
LibFFI — это библиотека интерфейса внешних функций, позволяющая произвольно вызывать собственную функцию без указателей и связывать указатели функции для универсальных функций, которые принимают переменные аргументы. Она используется для привязки нативного кода в современных скриптовых языках.

Вебсайт: http://sourceware.org/libffi/
Поддерживаемые платформы: Windows, Linux, DOS
Заголовки: ffi.bi
Версия заголовков: 3.0.10

Примеры

Hello world:
#include "ffi.bi"

' Простой эквивалент функции "puts"
Function printer cdecl (ByVal s As ZString Ptr) As Integer
    Print *s
    Return 42
End Function

' Инициализация аргументов информации векторов
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}

' Инициализация cif
Dim cif As ffi_cif
Dim result As ffi_status
result = ffi_prep_cif( _
    @cif,              _ ' вызов объекта интерфейса
    FFI_DEFAULT_ABI,   _ ' двоичный тип интерфейса
    1,                 _ ' количество аргументов
    @ffi_type_uint,    _ ' возвращаемый тип
    @args(0)           _ ' аргументы
)

' Вызов функции
Dim return_value As Integer
If result = FFI_OK Then
    s = @"Hello world"
    ffi_call(@cif, FFI_FN(@printer), @return_value, @values(0))

    'Значения содержат указатель на arg функции, так, что для того, чтобы
    'Вызвать puts() еще раз, нужно только изменить
    'Значение 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"

' Действует как puts с файлом во время вложения. 
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

' Выделение памяти для closure и функции связи
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
    Инициализация аргументов информации вектора
    Dim args(0 To 0) As ffi_type Ptr = {@ffi_type_pointer}
    
    ' Инициализация интерфейса вызова
    Dim cif As ffi_cif
    Dim prep_result As ffi_status = ffi_prep_cif( _
        @cif,            _ вызов объекта интерфейса
        FFI_DEFAULT_ABI, _ двоичный тип интерфейса
        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,        _ ' актуальная функция closure
            @ConsoleFile,    _ ' пользовательские данные, нашего консольного файла #
            PrinterBinding   _ ' указатель для связи
        )
        If prep_result = FFI_OK Then
            ' Вызов связи как натуральный вызов функции
            Dim Result As Integer
            Result = PrinterBinding("Hello World!")
            Print Using "Returned &"; Result
        End If
        
        Close ConsoleFile
    End If
End If

' Очистка
ffi_closure_free(closure)