type safe memory allocation with dart ffi
Asked Answered
C

1

6

I'm trying to make my code a little more robust when allocating memory for ffi.

I've written the following function:

void withMemory<T extends NativeType>(
    int size, void Function(Pointer<T> memory) action) {
  final memory = calloc<Int8>(size);
  try {
    action(memory.cast());
  } finally {
    calloc.free(memory);
  }
}

To call the above function I use:

withMemory<Uint32>(sizeOf<Uint32>(), (phToken) {
  // use the memory allocated to phToken
});

This works but as you can see I need to pass Uint32 twice as well as the sizeOf.

What I really want to write is:

withMemory<Uint32>((phToken) {
  // use the memory allocated to phToken
});

The problem is that you can't pass a generic type to either calloc or sizeOf without the error:

The type arguments to [...] must be compile time constants but type parameters are not constants. Try changing the type argument to be a constant type.

Is there any way around this problem?

Chiccory answered 17/6, 2021 at 11:46 Comment(1)
I guess the optimisations the Dart team wanted for FFI that @daco-harkes listed in github.com/dart-lang/sdk/issues/44621 meant the need to sacrifice being able to do sizeOf() or memory allocation for generics.Gluey
F
10

This can now be done with the Arena allocator from package:ffi.

using((Arena arena) {
  final p = arena<Uint32>();
  // Use the memory allocated to `p`.
}
// Memory freed.

Documentation:

Friesen answered 18/10, 2021 at 7:5 Comment(2)
thanks for pointing that out! completely didn't realise that Arena was available or that it makes this kind of usage possible.Gluey
Nice one Daco! This is really useful.Batik

© 2022 - 2024 — McMap. All rights reserved.