我想将JavaScript函数作为参数传递给从WebAssembly导出的函数,并以函数指针作为参数。
考虑以下示例:
JavaScript代码:
function foo() {
console.log("foo");
}
wasmInstance.exports.expects_funcptr(foo);
C代码:
typedef void(*funcptr_type)(void);
void expects_funcptr(funcptr_type my_funcptr)
{
my_funcptr();
}
我不使用Emscripten ,但他们在其“与代码交互”页面上的主题部分为https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-function-pointers-from-c。为此,他们有一个名为addFunction
的函数。
我在这里查看了其实现:https://github.com/emscripten-core/emscripten/blob/incoming/src/support.js#L755
而且似乎很……骇客。看起来他们正在创建一个新的wasm模块,该模块将javascript函数作为导入并将其导出为wasm函数。只有这样,他们才能将功能添加到WebAssembly表中。
有更好的方法吗?
编辑:
这是我目前正在处理的方式。通过使用以下函数将JS函数转换为WASM,我可以像这样将JS函数传递给WASM:
// How the above example would be called using the converter function.
wasmInstance.exports.expects_funcptr(convertFunction(foo, Types.VOID));
// The actual converter function (minus some details for simplicity)
function convertFunction(func, ret, params) {
// Construct a .wasm binary by hand
const bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // magic
0x01, 0x00, 0x00, 0x00, // version
// ... generate type, import, export sections as well
]);
const module = new WebAssembly.Module(bytes);
const instance = new WebAssembly.Instance(module, {
a: {
b: func
}
});
const ret = table.length;
table.grow(1);
table.set(ret, instance.exports.f);
return ret;
}
这是显示概念的粗略示例。实际的实现会检查函数是否已经转换,处理错误等。
答案 0 :(得分:1)
功能表是Wasm中功能指针的原语。您将必须使用一个函数指针。管理这个单独的地址空间可能非常棘手,并且emscripten中的所有“ hacky”代码都是为了确保安全地完成此操作。在您自己的代码中,您不需要像emscripten那样强制执行许多不变量,因此您可以摆脱其中的大部分。也很高兴在评论中对此进行澄清。
答案 1 :(得分:0)
您可以通过 emscripten 导出的函数帮助检查这个简单的生成器