调用c++_WebAssembly: 在C代码中调用JS的函数
0. 前提知識(shí)點(diǎn)
在index.html寫測(cè)試代碼
<script>var Module = {};Module.onRuntimeInitialized = () => {// 在這個(gè)回調(diào)中調(diào)用wasm中的方法}; </script> <!-- 膠水層代碼要放在后臺(tái) --> <script src="test.js"></script>1. 在C中調(diào)用JS函數(shù)之a(chǎn)ddFunction
Emscripten提供了多種在C環(huán)境調(diào)用JavaScript的方法,包括:
前3種方法點(diǎn)擊鏈接就可以查看詳細(xì)的使用說(shuō)明
下面著重描述下第4種方法,主要結(jié)合Calling JavaScript functions as function pointers from C實(shí)踐一下
You can use addFunction to return an integer value that represents a function pointer. Passing that integer to C code then lets it call that value as a function pointer, and the JavaScript function you sent to addFunction will be called.你可以使用addFunction這個(gè)函數(shù)的返回值(數(shù)字)來(lái)代表這個(gè)函數(shù)的指針。然后將該指針(數(shù)字)傳遞給C代碼,然后讓其將該值作為函數(shù)指針進(jìn)行調(diào)用,發(fā)送給addFunction的JavaScript函數(shù)將被調(diào)用。
由上面的說(shuō)明可以推測(cè)出Module有一個(gè)addFunction的方法,返回值是一個(gè)數(shù)字類型。
在嘗試調(diào)用的時(shí)候,發(fā)現(xiàn)提示說(shuō)要在編譯的時(shí)候?qū)С鲞@個(gè)函數(shù)
docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcc test.cc -o test.js # 要在這里加上-s EXTRA_EXPORTED_RUNTIME_METHODS="['addFunction']"再次調(diào)用時(shí)又發(fā)現(xiàn)要設(shè)置wasm table成為可以grow的
此時(shí)要在編譯腳本中再加上一行
-s ALLOW_TABLE_GROWTHYou should build with -s ALLOW_TABLE_GROWTH to allow new functions to be added to the table. Otherwise by default the table has a fixed size.加上編譯后,再次運(yùn)行,發(fā)現(xiàn)叕報(bào)錯(cuò)了,缺少函數(shù)簽名
查看文檔
When using addFunction on LLVM wasm backend, you need to provide an additional second argument, a Wasm function signature string. Each character within a signature string represents a type. The first character represents the return type of a function, and remaining characters are for parameter types. - 'v': void type - 'i': 32-bit integer type - 'j': 64-bit integer type (currently does not exist in JavaScript) - 'f': 32-bit float type - 'd': 64-bit float type原來(lái)是addFunction的第二個(gè)參數(shù)需要標(biāo)明函數(shù)的返回值類型,及參數(shù)類型,再次修改
終于成功了,此時(shí)已得到了函數(shù)的指針,將其傳入到C代碼中就可以調(diào)用了。
下面看下C代碼的實(shí)現(xiàn):
// 聲明函數(shù)簽名,在JS中調(diào)用addFunction時(shí),第二個(gè)函數(shù)的簽名要與此聲明保持一致 typedef void testExternalJSMethod(int p);// 導(dǎo)出一個(gè)接收函數(shù) EM_PORT_API (void) pass_fn_ptr(int ptr) {((testExternalJSMethod*)ptr)(1); } // js Module.onRuntimeInitialized = () => {function jsFunction(i) {console.log('定義在js中的function');console.log('從c中傳來(lái)的參數(shù): ', i);}// 這里說(shuō)明下,C語(yǔ)言是先聲明函數(shù)返回的類型,所以這里要先寫返回值的類型,再寫其他參數(shù)的類型var fPtr = Module.addFunction(jsFunction, 'vi');Module._pass_fn_ptr(fPtr); };最后看下輸出結(jié)果:
2. addFunction的優(yōu)點(diǎn)
X. 參考文檔
總結(jié)
以上是生活随笔為你收集整理的调用c++_WebAssembly: 在C代码中调用JS的函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 二叉树为空意味着二叉树_程序员的进阶课-
- 下一篇: go 指针变量和普通变量的转化_7.8