Array<T extends NativeType>.variable constructor

  1. @Since('3.6')
const Array<T extends NativeType>.variable([
  1. int dimension2,
  2. int dimension3,
  3. int dimension4,
  4. int dimension5,
])

Annotation to specify a variable length Array in Structs.

Can only be used on the last field of a struct. The last field of the struct is not taken into account in sizeOf. Using an AllocatorAlloc.call will not allocate any backing storage for the variable length array. Instead use Allocator.allocate and calculate the required number of bytes manually.

import 'dart:ffi';
import 'package:ffi/ffi.dart';

final class MyStruct extends Struct {
  @Size()
  external int length;

  @Array.variable()
  external Array<Uint8> inlineArray;

  static Pointer<MyStruct> allocate(Allocator allocator, int length) {
    final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * length;
    final result = allocator.allocate<MyStruct>(lengthInBytes);
    result.ref.length = length;
    return result;
  }
}

void main() {
  final myStruct = MyStruct.allocate(calloc, 10);
}

The variable lenght is always the outermost dimension of the array.

import 'dart:ffi';
import 'package:ffi/ffi.dart';

final class MyStruct extends Struct {
  @Size()
  external int length;

  @Array.variable(10, 10)
  external Array<Array<Array<Uint8>>> inlineArray;

  static Pointer<MyStruct> allocate(Allocator allocator, int length) {
    final lengthInBytes = sizeOf<MyStruct>() + sizeOf<Uint8>() * length * 100;
    final result = allocator.allocate<MyStruct>(lengthInBytes);
    result.ref.length = length;
    return result;
  }
}

Accessing variable length inline arrays of structs passed by value in FFI calls and callbacks is undefined behavior. Accessing variable length inline arrays in structs passed by value is undefined behavior in C.

For more information about variable length inline arrays in C, please refer to: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html.

Do not invoke in normal code.

Implementation

@Since('3.6')
const factory Array.variable([
  int dimension2,
  int dimension3,
  int dimension4,
  int dimension5,
]) = _ArraySize<T>.variable;