Dart FFI and arrays

307 views
Skip to first unread message

Chris Norman

unread,
Apr 8, 2021, 4:46:31 PM4/8/21
to mi...@dartlang.org
Hi all,
I'm currently writing some Dart bindings for a library written in C++. I am trying to bind a function defined as follows:

// From synthizer.h:
SYZ_CAPI syz_ErrorCode syz_echoSetTaps(syz_Handle handleunsigned int n_taps, struct syz_EchoTapConfig *taps);

Far as I can tell, `taps` is supposed to be an array of ` syz_EchoTapConfig` structs.

Here is my function (it's mercifully short):

  /// Sets the taps of the echo.
  void setTaps(List<EchoTapConfig>? taps) {
    if (taps == null || taps.isEmpty) {
      synthizer
          .check(synthizer.synthizer.syz_echoSetTaps(handle.value0nullptr));
    } else {
      final a = Array<Pointer<syz_EchoTapConfig>>(taps.length);
      for (var i = 0i < taps.lengthi++) {
        final t = taps[i];
        final tc = calloc<syz_EchoTapConfig>();
        tc.ref
          ..delay = t.delay
          ..gain_l = t.gainL
          ..gain_r = t.gainR;
        a[i] = tc; // This line causes a crash.
        print(a);
      }
      synthizer.check(
          synthizer.synthizer.syz_echoSetTaps(handle.valuetaps.lengtha[0]));
    }
  }

I'm reasonably sure my problem lies with my use of the Array class, and (more specifically), then StructArray extension, which gives it the [] operator.

Can anyone suggest what I can do next? I have tried googling, but I can't find aexamples of using the Array class, neither in the examples for dart:ffi, or the ffi package.

If you need more info, please tell me. I'm by no means a C++ programmer, and I'm not really sure what info to provide to be useful rather than extraneously verbose.

Thanks in advance.


Take care,

Chris Norman

Simon

unread,
Apr 9, 2021, 3:06:58 AM4/9/21
to Dart Misc, chris....@googlemail.com
Indeed, the problem is that you're manually creating instances of Array. As the documentation points out, the constructors are only meant to be used as annotations on a struct class and we're not supposed to invoke then in normal code.
You can allocate multiple structs in Dart, which is what the C library probably expects:

  } else {
     final a = calloc<syz_EchoTapConfig>(taps.length);
     for (var i = 0; i < taps.length; i++) {
       final t = taps[i];
       final tc = a[i];
       tc
         ..delay = t.delay
         ..gain_l = t.gainL
         ..gain_r = t.gainR;
     }
    synthizer.check(
        synthizer.synthizer.syz_echoSetTaps(handle.value, taps.length, a));
     calloc.free(a);
   }
Reply all
Reply to author
Forward
0 new messages