如何通过dart ffi向win32函数传递回调?

rvpgvaaj  于 2023-09-28  发布在  其他
关注(0)|答案(1)|浏览(178)

我正在尝试将MIDI设备连接到Windows上运行的Flutter应用程序。我用的是win32和dart ffi我有以下内容:

final Pointer<HMIDIIN> hMidiDevice = malloc();

Pointer<NativeFunction<MidiInProc>> callbackPointer =
    Pointer.fromFunction(midiInCallback);

final result = midiInOpen(
  hMidiDevice,
  0,
  callbackPointer.address,
  0,
  CALLBACK_FUNCTION,
);
midiInStart(hMidiDevice.value);

midiInOpen将指向函数的指针作为第三个参数。下面是我的回调方法:

static void midiInCallback(
    int hMidiIn,
    int wMsg,
    int dwInstance,
    int dwParam1,
    int dwParam2,
) {
    print('Message: $wMsg dwParam1: $dwParam1');
}

这编译并与连接的USB MIDI设备一起工作。但是,当我在MIDI设备上按下一个键时,我得到以下错误:

../../third_party/dart/runtime/vm/runtime_entry.cc: 3657: error: Cannot invoke native callback outside an isolate.
pid=11004, thread=21860, isolate_group=(nil)(0000000000000000), isolate=(nil)(0000000000000000)
isolate_instructions=0, vm_instructions=7ffef50837c0
  pc 0x00007ffef51a3732 fp 0x00000057468ff990 angle::PlatformMethods::operator=+0x322d8a
-- End of DumpStackTrace

这是什么意思,我可以做什么,使我的回调函数与MIDI数据调用?

fcy6dtqo

fcy6dtqo1#

Dart 3.1引入了NativeCallable.listener,它可用于创建回调,允许本机代码从任何线程调用Dart代码。仅支持void函数。
下面是示例的修改版本,现在包含了NativeCallable.listener

final Pointer<HMIDIIN> hMidiDevice = malloc();

final nativeCallable = NativeCallable<MidiInProc>.listener(midiInCallback);

final result = midiInOpen(
  hMidiDevice,
  0,
  nativeCallable.nativeFunction.address,
  0,
  CALLBACK_FUNCTION,
);
midiInStart(hMidiDevice.value);

// Don't forget to close the callback when it is no longer needed.
// Otherwise, the Isolate will be kept alive indefinitely.
nativeCallable.close();

相关问题