dart-archive/ffi

Convert a List<int> into a Pointer<Uint32>

jorgegaticav opened this issue · 3 comments

Hi everyone,

Is it possible to convert a List<int> into a Pointer<Uint32>?
I have a native function:

 void Function(Pointer<Uint32>, int, int, int, int)> read = _lookup<
   NativeFunction<
      Void Function(Pointer<Uint32>, Int64, Int64, Int64, Int64)>>('read')
   .asFunction();

that should be accessed from dart using this method:

read(List<int> buf, int x, int y, int width, int height)

I am not sure how to do the conversion. Any suggestions?

Following instructions in issue #27
I think this could be an option:

final ptr = malloc.allocate<Uint32>(buf.length);
for(int i = 0; i < dest.length; i++){
   ptr[i] = buf[i];
}
read(buf, x, y, w, h)
malloc.free(ptr);

A Dart List<int> lives in Dart memory. And a Pointer points to native memory.

So we'll have to copy the data from Dart to native memory.

final readNative = d.lookupFunction<
    Void Function(Pointer<Uint32>, Int64, Int64, Int64, Int64),
    void Function(Pointer<Uint32>, int, int, int, int)>('read');

read(List<int> buf, int x, int y, int width, int height) {
  final length = buf.length;
  final pointer = calloc<Uint32>(length + 1); // +1 if null-terminated.
  for (int index = 0; index < length; index++) {
    pointer[index] = buf[index];
  }
  readNative(pointer, x, y, width, height);
  calloc.free(pointer);
}

or

read(List<int> buf, int x, int y, int width, int height) {
  using((Arena arena) {
    final length = buf.length;
    final pointer = arena<Uint32>(length + 1); // +1 if null-terminated.
    for (int index = 0; index < length; index++) {
      pointer[index] = buf[index];
    }
    readNative(pointer, x, y, width, height);
  });
  // After `using` all allocations in `arena` are freed.
}

@jorgegaticav beat me to it!

A Dart List<int> lives in Dart memory. And a Pointer points to native memory.

So we'll have to copy the data from Dart to native memory.

final readNative = d.lookupFunction<
    Void Function(Pointer<Uint32>, Int64, Int64, Int64, Int64),
    void Function(Pointer<Uint32>, int, int, int, int)>('read');

read(List<int> buf, int x, int y, int width, int height) {
  final length = buf.length;
  final pointer = calloc<Uint32>(length + 1); // +1 if null-terminated.
  for (int index = 0; index < length; index++) {
    pointer[index] = buf[index];
  }
  readNative(pointer, x, y, width, height);
  calloc.free(pointer);
}

or

read(List<int> buf, int x, int y, int width, int height) {
  using((Arena arena) {
    final length = buf.length;
    final pointer = arena<Uint32>(length + 1); // +1 if null-terminated.
    for (int index = 0; index < length; index++) {
      pointer[index] = buf[index];
    }
    readNative(pointer, x, y, width, height);
  });
  // After `using` all allocations in `arena` are freed.
}

@jorgegaticav beat me to it!

Thanks @dcharkes, using calloc was the correct way to go, with malloc it didn't work properly.