假设有这个 C 代码,
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
void *add_ptr() { return add; }
void *mul_ptr() { return mul; }
int op(int a, int b, int (*op) (int a, int b)) { return op(a, b); }
void *op_ptr() { return op; }
并使用常规的 clang 8/9 编译它以构建一个 wasm 文件,
clang --target=wasm32 a.c -nostdlib -Wl,--no-entry -Wl,--export=add -Wl,--export=mul -Wl,--export=mul_ptr -Wl,--export=add_ptr -Wl,--export=op -Wl,--export=op_ptr -o a.wasm
并使用 html 页面运行它,例如,
<script>
WebAssembly.instantiateStreaming(fetch('a.wasm')).then(result => alert(`
add: ${result.instance.exports.add(2, 3)}
mul: ${result.instance.exports.mul(2, 3)}
op_add: ${result.instance.exports.op(2, 3, result.instance.exports.add_ptr())}
op_mul: ${result.instance.exports.op(2, 3, result.instance.exports.mul_ptr())}
add_ptr: ${result.instance.exports.add_ptr()}
mul_ptr: ${result.instance.exports.mul_ptr()}
op_ptr: ${result.instance.exports.op_ptr()}
add.name: ${result.instance.exports.add.name}
mul.name: ${result.instance.exports.mul.name}
add_ptr.name: ${result.instance.exports.add_ptr.name}
mul_ptr.name: ${result.instance.exports.mul_ptr.name}
op.name: ${result.instance.exports.op.name}
`));
</script>
这使,
add: 5
mul: 6
op_add: 5
op_mul: 6
add_ptr: 1
mul_ptr: 2
op_ptr: 3
add.name: 0
mul.name: 1
add_ptr.name: 2
mul_ptr.name: 3
op.name: 4
获取
add
的指针地址的可靠方法是什么?/mul
在没有 {add|mul}_ptr
的 WebAssembly 实例中喜欢功能?不能是.name
如op.name
不同于 op_ptr
结果。这里的最终目的(我已将我的用例简化为这个片段)是拥有
add
或 mul
地址并将其传递给 op
像获取函数指针的函数。
最佳答案
对于 WebAssembly 函数以及它们包含的可执行代码,它们位于与数据不同的命名空间中。因此,您无法获得指向函数的地址/指针并将其用作调用它的间接机制。
我认为您在代码中看到的是 WebAssembly 模块的 function section 中的函数索引。 .
add_ptr: 1
mul_ptr: 2
op_ptr: 3
可以通过底层
call_indirect
执行动态函数调用WebAssembly 操作。这允许您调用存储在 table section 中的函数。 .但是,我不确定 clang 编译器是否支持利用此功能的方式来支持您正在寻找的行为。
关于javascript - 获取 WebAssembly 导出函数的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59282861/