代码之家  ›  专栏  ›  技术社区  ›  acm

在emscripten中处理输出缓冲区

  •  0
  • acm  · 技术社区  · 6 年前

    假设我有一个C API,如下所示:

    void get_result_buffer(context* ctx, void** result, size_t* result_size);
    

    在哪里? context 是某种任意不透明的上下文类型保持状态。这种说法的目的是

    context* ctx = ...;
    
    do_something_with_context(ctx, ...);
    
    void* result_buffer = 0;
    size_t result_buffer_size = 0;
    get_result_buffer(ctx, &result_buffer, &result_buffer_size);
    
    /* Now result_buffer and result_buffer_size are meaningful and populated with the results of having called `do_something_with_context`. */
    

    这个 result_buffer 属于 上下文 对象,因此调用方不需要释放它。现在我想打电话 get_result_buffer 来自Emscripten。我可以很容易地设置 cwrap 为此,它看起来像:

    wrap_get_result_buffer = something.cwrap(
        'get_result_buffer',
        null,
        ['number', 'number', 'number']
    )
    

    但我不清楚如何设置,以便在JS中使用out参数。理想情况下,在最后,我会有一个看起来像字节缓冲区的东西,其中包含 result out参数,长度如 result_size out参数。

    似乎我传入的值需要以某种方式进行分配,然后我将作为 number 类型参数,但我不知道如何在JS/Emscripten层中执行此操作。同样,在调用之后,我希望这些值现在已经被发出的C代码更新了,但是我不清楚如何将现在填充的数据提取到某种JS字节数组中。

    关于如何执行此操作或指向示例代码的指针有任何指导吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   acm    6 年前

    好啊。我知道了。对于未来的emscripteners,您需要执行如下操作。

    var out_data_ptr = Module._malloc(8)
    var out_data_array = new Uint32Array(Module.HEAPU32.buffer, out_data_ptr, 2)
    wrap_get_result_buffer(context, out_data_ptr, out_data_ptr + 4)
    var response_uint8_array = new Uint8Array(Module.HEAPU8.buffer, out_data_array[0], out_data_array[1])
    Module._free(out_data_ptr)
    

    这里的操作理论是我们创建一个两元素数组,它将存储要通过调用来填充的“槽”。 get_result_buffer 然后在上面构建一个视图,将其作为两个 number 兼容元素。然后我们把它们传给我们的 获取结果缓冲区 功能如上所述 cwrap . 之后,堆内存 context 引用可从这些槽中访问,然后可用于构造 Uint8Array 它提供对结果中字节的JS级访问。