【问题标题】:Export a structure from C to wasm?将结构从 C 导出到 wasm?
【发布时间】:2021-05-27 03:36:02
【问题描述】:

我有一个包含以下声明的头文件:

typedef struct {
        double *vals;
        int len;
} List;

typedef struct {
        List *list;
        int sample;
} MarkedList;

我正在编译一个包含这些定义的 C 文件和一个接受 const *MarkedList 的函数:

clang --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry src/filename.c -o target/res/filename.wasm

我正在加载该文件:

WebAssembly.instantiateStreaming(fetch('res/mean.wasm'), {})
.then(results => {
    console.log(results)
});

然后控制台向我显示了一个带有 instance.exports 的 wasm 模块,其中包含我定义的函数,但 不是 结构。如何从我的 javascript results 对象访问结构?

【问题讨论】:

  • 您不能导出类​​或结构,只能导出实例,即符号。如果您创建 MarkedList 的全局实例,您应该能够导出它(即它在内存中的地址)
  • @sbc100 哦,谢谢。如何在 JS 中分配或实例化结构?
  • 有几种方法。最低级别的方法是致电Module._malloc。还有更高级别的绑定解决方案,例如 embind:emscripten.org/docs/porting/connecting_cpp_and_javascript/…

标签: javascript c webassembly


【解决方案1】:

为了解决这个问题,我更改了很多代码,但我会尽我所能写出我的整体解决方案的摘要。首先,我通过 clang 切换到 emcc,以便标准库 C 功能(如 malloc)在 wasm 中工作(参见How to implement "malloc" in Wasm)。虽然这是一个非常严厉的解决方案,但我相信 LTO 可以减少一些未使用的功能。

其次,我已经尽我所能封装ListMarkedList结构的API,以便仅将与仅与数字类型(包括指针)通信的有用函数导出到JS,符合WebAssembly 标准。因此,List *malloc_list(void)void push_list(List *l, double v) 在这种情况下是有意义的,但是任何使用依赖于结构的内存表示的 API(例如,访问单个字段)都是不可能的。

因此,虽然没有广泛适用的导出结构的方法,但有一些变通方法可以在 C 中尽可能多地在 JS 中保持尽可能少,并且我能够从列表中完成我需要的和 MarkedList 结构。

【讨论】:

  • > 因此,虽然没有广泛适用的导出结构的方法,但如果您使用的是 Emscripten,则有 - Embind 允许导出结构、类等。 emscripten.org/docs/porting/connecting_cpp_and_javascript/…
  • @RReverser 我遇到了那个页面,我的理解是它只适用于 C++ 类,它最终以基本上是上面提出的解决方案,但使用 C++ 而不是 C
  • 没错,但是现在你需要在 C 和 JS 端手动提供自定义绑定。相反,您可以仅为 Embind 注释创建一个 cpp 文件,并将其与您的 C 代码库一起编译 + 链接,并让 Emscripten 为您完成导出和绑定工作。这主要是一个缩放问题。
猜你喜欢
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 2013-08-12
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多