gpt4 book ai didi

dart - 如何将 native void 指针传递给 Dart 隔离 - 无需复制?

转载 作者:行者123 更新时间:2023-12-03 19:13:45 31 4
gpt4 key购买 nike

我正在为 Dart 公开一个音频库(C 库)。要触发音频引擎,它需要一些初始化步骤(UI 非阻塞),然后使用执行函数触发音频处理,该函数是阻塞的(音频处理是一项繁重的任务)。这就是为什么我来阅读有关 Dart 隔离的原因。

我的第一个想法是我只需要调用隔离中的性能方法,但这似乎不可能,因为执行函数将引擎状态作为第一个参数 - 这个引擎状态是一个不透明的指针(指针在 dart:ffi )。当尝试使用计算函数将引擎状态传递给新的隔离时,Dart VM 返回错误 - 它无法将 C 指针传递给隔离。

我找不到将这些数据传递给隔离的方法,我认为这是由于主隔离的单独内存和我正在创建的内存。

所以,我可能应该在隔离中管理整个引擎状态,这意味着:

  • 创建引擎状态
  • 用一些选项(字符串)初始化它
  • 触发执行函数
  • 运行时控制音频

  • 我找不到任何关于如何在隔离中执行此操作的示例,但从主线程/隔离触发。既不是关于如何管理隔离内存(保持引擎状态并使用它)。我当然可以

    这是我想要做的一个非孤立的例子:

    Pointer<Void> engineState = createEngineState();
    initEngine(engineState, parametersString);
    startEngine(engineState);
    perform(engineState);

    在运行时,由 UI 操作触发(例如更改 slider 值或单击按钮):

    setEngineControl(engineState, valueToSet);
    double controleValue = getEngineControl(engineState);

    引擎状态可以封装在一个类中,我认为这并不重要。
    无论是类还是不透明数据类型,我都找不到如何管理和保持这种状态,以及从主线程执行触发器(在隔离中处理)。任何的想法 ?

    提前,谢谢。

    PS:我注意到,在写作时,我的问题/解释可能不准确,我不得不说我在这里有点迷路,因为我从未使用过 Dart Isolates。请告诉我是否缺少某些信息。

    编辑 4 月 24 日:
    它似乎正在创建和管理 Isolate 中的对象状态。但主要问题没有解决。因为 perform 方法实际上是在未完成时阻塞的,所以没有办法在隔离中仍然接收消息。
    我首先想到的一个选项是使用 performBlock 方法,它只执行一个音频样本 block 。像这样 :

    while(performBlock(engineState)) {
    // listen messages, and do something
    }

    但这似乎不起作用,在音频性能完成之前,进程仍然被阻塞。即使在隔离中的异步方法中调用此循环,它也会阻塞,并且不会读取任何消息。

    我现在考虑通过 Pointer<Void>的可能性在主隔离中管理到另一个,然后是工作人员(仅用于执行方法),然后能够从主隔离触发一些控制方法。

    isolate Dart 包提供了一个注册表子库来管理一些共享内存。但是仍然不可能在隔离之间传递 void 指针。

    [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument(s): Native objects (from dart:ffi) such as Pointers and Structs cannot be passed between isolates.



    有没有人遇到过这种情况?

    最佳答案

    可以得到一个地址,这个 Pointer指向一个数字并构造一个新的Pointer从这个地址(见 Pointer.address Pointer.fromAddress() )。由于数字可以在隔离之间自由传递,这可以用来在它们之间传递本地指针。
    在您的情况下,可以这样做,例如,像这样(我使用 Flutter 的 compute 使示例更简单,但显然也可以显式使用 Send/ReceivePort s)

    // Callback to be used in a backround isolate.
    // Returns address of the new engine.
    int initEngine(String parameters) {
    Pointer<Void> engineState = createEngineState();
    initEngine(engineState, parameters);
    startEngine(engineState);
    return engineState.address;
    }

    // Callback to be used in a backround isolate.
    // Does whichever processing is needed using the given engine.
    void processWithEngine(int engineStateAddress) {
    final engineState = Pointer<Void>.fromAddress(engineStateAddress);
    process(engineState);
    }

    void main() {
    // Initialize the engine in a background isolate.
    final address = compute(initEngine, "parameters");
    final engineState = Pointer<Void>.fromAddress(address);

    // Do some heavy computation in a background isolate using the engine.
    compute(processWithEngine, engineState.address);
    }

    关于dart - 如何将 native void 指针传递给 Dart 隔离 - 无需复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61309496/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com