dart-archive / ffi

Utilities for working with Foreign Function Interface (FFI) code

Home Page:https://pub.dev/packages/ffi

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Finalizing typed list to free its native memory

DanielSWolf opened this issue · comments

I have a number of native libraries for sound processing that I want to expose as safe Dart wrappers. Each of these C functions takes one or more pointers to memory buffers, then performs some operation reading from or writing to these buffers. Often, a buffer used to get the output of one function can then be used as input to the next, preventing unnecessary copies.

My problem is how to represent these buffers on the Dart side. In #31, it was recommended to allocate memory on the native side, then use Pointer.asTypedList() to create the Dart counterpart. However, unless these buffers are static, I'll need to free them at some point. Ideally, this should happen automatically when the typed list on the Dart side is CG'ed. But the result of asTypedList is just a Float32List, which doesn't implement Finalizable, so I don't see a way of attaching a finalizer.

Ideally, I'd want one of the following:

  1. asTypedList returns a value that implements Finalizable. This way, I can attach a native finalizer to it that frees the native memory.
  2. dart:ffi offers a way to create a ByteBuffer that manages its own memory and exposes a native pointer to that memory.

Without support from dart:ffi, the best I can think of is to write a new class that implements List<double> and wraps a Float32List along with the code for automatically freeing the native memory on finalization. But that would introduce even more indirection when accessing its items from Dart, probably eliminating the performance benefits gained from not copying the buffers.

Instead of asTypedList returning an implements Finalizable, we would could add a finalizer argument to that call.

XyzList Pointer<Xyz>.asTypedList(int length, {NativeFinalizerFunction finalizer})

This is being tracked in:

I didn't find the existing ticket because I was looking in the wrong repo. Thanks for the pointer!

Closing this as a duplicate.