在 emscripten 中处理输出缓冲区

Handling output buffers in emscripten

假设我有一个 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 属于 context 对象,因此调用者不需要释放它。现在我希望能够从 Emscripten 调用 get_result_buffer。我可以很容易地为此设置 cwrap,它看起来像:

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

但我不清楚如何设置才能使 JS 中的输出参数 "work"。理想情况下,最后我会得到一些看起来像字节缓冲区的东西,其中包含 result out 参数指向的数据副本,其长度由 result_size out 参数描述。

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

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

好的。我想通了。对于未来的 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 填充的 'slots',然后构造一个视图,将其公开为两个number 兼容元素。然后我们将它们传递给我们的 get_result_buffer 函数,就像上面使用 cwrap 提升的那样。之后,context 所指的堆内存可以从这些槽中访问,然后可以使用这些槽来构造一个 Uint8Array,它提供对结果中字节的 JS 级访问。