[wasm] 調(diào)用C中的自定義方法

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>

參考

MDN: 編譯 C/C++ 為 WebAssembly

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容