我正在为 Dart 公开一个音频库(C 库)。要触发音频引擎,它需要一些初始化步骤(UI 非阻塞),然后使用执行函数触发音频处理,该函数是阻塞的(音频处理是一项繁重的任务)。这就是为什么我来阅读有关 Dart 隔离的原因。
我的第一个想法是我只需要调用隔离中的性能方法,但这似乎不可能,因为执行函数将引擎状态作为第一个参数 - 这个引擎状态是一个不透明的指针(指针在 dart:ffi )。当尝试使用计算函数将引擎状态传递给新的隔离时,Dart VM 返回错误 - 它无法将 C 指针传递给隔离。
我找不到将这些数据传递给隔离的方法,我认为这是由于主隔离的单独内存和我正在创建的内存。
所以,我可能应该在隔离中管理整个引擎状态,这意味着:
- 创建引擎状态
- 用一些选项(字符串)初始化它
- 触发执行功能
- 在运行时控制音频
我找不到任何关于如何在隔离中执行此操作的示例,但从主线程/隔离触发。既不是关于如何管理隔离内存(保持引擎状态并使用它)。我当然可以
这是我想要做的一个非孤立的例子:
Pointer<Void> engineState = createEngineState();
initEngine(engineState, parametersString);
startEngine(engineState);
perform(engineState);
在运行时,由 UI 操作触发(例如更改滑块值或单击按钮):
setEngineControl(engineState, valueToSet);
double controleValue = getEngineControl(engineState);
引擎状态可以封装在一个类中,我认为这并不重要。无论是类还是不透明数据类型,我都找不到如何管理和保持这种状态,以及从主线程执行触发器(在隔离中处理)。任何想法 ?
提前,谢谢。
PS:我注意到,在写作时,我的问题/解释可能不准确,我不得不说我在这里有点迷路,因为我从未使用过 Dart Isolates。请告诉我是否缺少某些信息。
编辑 4 月 24 日:它似乎在 Isolate 中创建和管理对象状态。但主要问题没有解决。因为 perform 方法实际上是在未完成时阻塞的,所以没有办法在隔离中仍然接收消息。我首先想到的一个选项是使用 performBlock 方法,它只执行一个音频样本块。像这样 :
while(performBlock(engineState)) {
// listen messages, and do something
}
但这似乎不起作用,在音频性能完成之前,进程仍然被阻塞。即使在隔离中的异步方法中调用此循环,它也会阻塞,并且不会读取任何消息。
我现在考虑将Pointer<Void>
托管在主隔离中的可能性传递给另一个,然后是工作人员(仅用于执行方法),然后能够从主隔离中触发一些控制方法。
隔离Dart 包提供了一个注册表子库来管理一些共享内存。但是仍然不可能在隔离之间传递 void 指针。
[错误:flutter/lib/ui/ui_dart_state.cc(157)] 未处理的异常:无效参数:指针和结构等原生对象(来自 dart:ffi)不能在隔离之间传递。
有没有人遇到过这种情况?