我遇到了一些情况。
一个我们需要一些胶水代码:
int addThree(uint8_t *buf, int len) {
uint8_t *item;
uint8_t *end = buf + len;
for (item = buf; item<end; item++) {
*item += 3;
}
return 0;
}
但是,简单来说,我们只需要使用 .wasm 文件
int adder (int a, int b) {
return a + b;
}
那么,胶水代码有什么作用呢? 我找不到一些文档。
什么胶水代码? 您似乎从一些 Wasm 教程中复制了两个函数( addThree()
和adder()
)? 它们似乎只是示例函数,实际上并没有做太多事情,只是用来演示一个简单的 Wasm 教程。 这两个函数都没有复杂的签名,应该可以在没有任何胶水代码的情况下调用。
但是,这不是我的重点。 从一些文档中,它解释如下:
从长远来看,带有类型对象和 GC 的 wasm 可能会有所帮助。 这是这里的意思吗?
否则,我不确定如何在短期或中期删除任何胶水代码。 围绕 C/C++ 事物形成一个外壳,使它们看起来像 JS 事物,这需要大量的工作。 例如,粘合代码必须包含将 C 字符串转换为 JS 字符串的方法,反之亦然。 在 C++ 级别,支持在 JS 中扩展 C++ 类并在 JS 中实现虚拟方法需要相当多的技巧。 一般来说,从 wasm 到 JS 访问 Web API 需要大量的胶水。
和别的:
Emscripten 需要大量的 JavaScript “胶水”代码来处理内存分配、内存泄漏和许多其他问题,这些问题已经包含在提供的模板中。 使用它比必须自己写出来更容易
当我遇到一些简单的 C/C++ 代码时,我可以通过编译它轻松地使用 wasm,而export.xxxFn()
。
int adder (int a, int b) {
return a + b;
}
当我使用使用 Buffer 的代码时,我更喜欢使用胶水代码。
# C/C++
int addThree(uint8_t *buf, int len) {
uint8_t *item;
uint8_t *end = buf + len;
for (item = buf; item<end; item++) {
*item += 3;
}
return 0;
}
# deal with buffer in JS
...
let dataHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, nDataBytes);
dataHeap.set(new Uint8Array(buffer_pcm.buffer));
...
所以,我可以得出结论,当我将 Buffer 转移到 WASM 时,我需要粘合代码来处理内存分配、内存泄漏和许多其他问题吗?
上面注释中描述的粘合代码是 Emscripten 生成的 JavaScript 加载器。 它完全按照注释说的做:在 JS 和 C++ 数据表示(例如字符串)之间以及不同对象表示之间(即为 C++ 对象创建 JS 代理对象)之间进行转换。 它还创建所需的类型化数组。
正如您所注意到的,对于简单的情况,例如您用作示例的两个函数,您可以省去 Emscripten 加载程序。 它们都不需要任何复杂的粘合代码:每个都只需要一个 JS 文件来加载 Wasm 文件(在第二个示例中,addThree 的 wasm 文件也需要创建 Uint8Array)。
最后,内存分配由 Wasm 代码处理,它应该包括一份来自 musl 的 malloc 副本(尽管 Emscripten 实际上仍然包括它的 malloc,而不是使用 musl 的)。 只需在完成 C/C++ 代码后释放内存,即可以标准方式避免内存泄漏,Wasm 在这里没有什么特别要求。
最终,您只需要实际使用的胶水代码,这取决于您的代码所做的跨边界调用(从 JS 到 C++,从 C++ 到 JS)。
这个问题可以关闭,这是一个关于 Emscripten 的问题,而不是 WebAssembly 设计本身的错误。
非常感谢
最有用的评论
上面注释中描述的粘合代码是 Emscripten 生成的 JavaScript 加载器。 它完全按照注释说的做:在 JS 和 C++ 数据表示(例如字符串)之间以及不同对象表示之间(即为 C++ 对象创建 JS 代理对象)之间进行转换。 它还创建所需的类型化数组。
正如您所注意到的,对于简单的情况,例如您用作示例的两个函数,您可以省去 Emscripten 加载程序。 它们都不需要任何复杂的粘合代码:每个都只需要一个 JS 文件来加载 Wasm 文件(在第二个示例中,addThree 的 wasm 文件也需要创建 Uint8Array)。
最后,内存分配由 Wasm 代码处理,它应该包括一份来自 musl 的 malloc 副本(尽管 Emscripten 实际上仍然包括它的 malloc,而不是使用 musl 的)。 只需在完成 C/C++ 代码后释放内存,即可以标准方式避免内存泄漏,Wasm 在这里没有什么特别要求。
最终,您只需要实际使用的胶水代码,这取决于您的代码所做的跨边界调用(从 JS 到 C++,从 C++ 到 JS)。
这个问题可以关闭,这是一个关于 Emscripten 的问题,而不是 WebAssembly 设计本身的错误。