1. Module.ccall與EMSCRIPTEN_KEEPALIVE
JavaScript中可以借由wasm調(diào)用C中的自定義方法,
Module.ccall(
'myFunction', // C自定義方法的名字
null, // 返回值類型
null, // 入?yún)㈩愋? null, // 入?yún)?);
默認(rèn)情況下,Emscripten生成的代碼只會調(diào)用main()函數(shù),其他函數(shù)將被視為無用代碼。
為了避免這件事發(fā)生,我們需要在C函數(shù)名之前,添加EMSCRIPTEN_KEEPALIVE,它在emscripten.h中聲明。
例子,hello.c,
#include <stdio.h>
#include <emscripten/emscripten.h>
int main(int argc, char ** argv) {
printf("Hello World\n");
}
#ifdef __cplusplus
extern "C" {
#endif
int EMSCRIPTEN_KEEPALIVE myFunction(int argc, char ** argv) {
printf("我的函數(shù)已被調(diào)用\n");
}
#ifdef __cplusplus
}
#endif
2. 修改編譯結(jié)果
編譯以上的hello.c文件,
$ emcc -o hello.html hello.c -s WASM=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']"
注:
(1)EXTRA_EXPORTED_RUNTIME_METHODS設(shè)置了Module的導(dǎo)出函數(shù),
不導(dǎo)出ccall的話,會報以下錯誤,
'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)
(2)為了使用Module.ccall,我們需要修改hello.html文件,
在文件末尾增加一個<script>標(biāo)簽,
<script>
setTimeout(()=>{
Module.ccall('myFunction', null, null, null); // 打?。何业暮瘮?shù)已被調(diào)用
}, 1000);
</script>
其中使用setTimeout的原因是,hello.html文件加載hello.js文件的方式是使用了async script。
<script async type="text/javascript" src="hello.js"></script>