dev.audiomixing.de - Zig Funktion per Dart FFI aufrufen

Zig Funktion per Dart FFI aufrufen

In meinem Beispiel übergebe ich aus Dart eine Liste mit unbestimmter Länge an eine Zig Funktion. Dort wird die Summe der Elemente des Arrays gebildet und an Dart zurückgegeben:

Zuerst erstelle ich ein Dart Projekt mit
dart init
Anschließend erstelle ich im Hauptverzeichnis des Projektes ein Unterverzeichnis mit Namen "linux_64" Dort hinein speichere ich die folgende Zig-Datei mit dem Namen "test06.zig":

const std = @import("std");
export fn sum(myArray: [*]const i32, arraySize: usize) i32 {
    var summe: i32 = 0;
    for (0..arraySize) |index| {
       summe += myArray[index];
    }
    return summe;
}
Anschließend führe ich den folgenden Befehl aus, um aus der zig-Datei eine Library zu generieren:
zig build-lib test06.zig -dynamic
Jetzt müssten die folgenden Dateien erstellt worden sein: "libtest06.so" und "libtest06.so.o". Wer möchte kann beim Erstellen der Librarys mit dem Parameter -ReleaseSmall die Filegröße noch verkleinern. Im bin-Verzeichnis erstelle ich die Datei "main.dart" und schreibe folgendes hinein:

import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';
            
void main(List<String> arguments) {
    final list = [1, 2, 3, 4, 5];
    final listPtr = intListToArray(list);
            
    final myLib = ffi.DynamicLibrary.open('../linux_64/libtest06.so');
    final mySum = myLib.lookupFunction<
    ffi.Int32 Function(ffi.Pointer<ffi.Int32>, ffi.Int32),
        int Function(ffi.Pointer<ffi.Int32>, int)
        >('sum');
            
    final result = mySum(listPtr, list.length);
    print('Result: $result');
    malloc.free(listPtr);
}
            
ffi.Pointer<ffi.Int32> intListToArray(List<int> list) {
    final ptr = malloc.allocate<ffi.Int32>(ffi.sizeOf<ffi.Int32>() * list.length);
    for (var i = 0; i < list.length; i++) {
        ptr[i] = list[i];
    }
    return ptr;
}
Anschließend führe ich die main.dart Datei mit dem folgenden Befehl aus:
dart run main.dart