Emscripten:JS 呼叫 C、C++
在瞭解 Emscripten 中,給大家簡單分享了 Emscripten
是什麼以及其使用場景。今天繼續分享如何使用 JS 呼叫 C/C++ 程式碼。
神奇的 main 函式
下面是瞭解 Emscripten 中的例子程式碼,只有一個 main
函式。
#include <stdio.h> int main(int argc, char ** argv) { printf("Emscripten show in browser...\n"); }
使用 Emscripten SDK
編譯後生成了對應的 html、js 和 wasm 檔案。
第一次編譯會較慢, 編譯完成後會在 ~/.emscripten_cache
生成快取目錄和檔案, 以後再次編譯就比較快了.
可以在火狐或者 Chrome
或者 Safari
上面執行 h_emcc.html
檔案.
這裡在火狐瀏覽器上面可以直接開啟 mz.html
檔案, 如果是在 Chrome
或者 Safari
需要執行下面命令:
emrun mz.html
或者指定瀏覽器開啟該檔案.
emrun --browser chrome mz.html
關於 emrun
的其他用法,可以使用 emrun --help
來檢視。這裡在瀏覽器可以看到對應 main
函式的輸出,說明 Emscripten
生成的程式碼預設會呼叫 main
函式。
EMSCRIPTEN_KEEPALIVE
既然 Emscripten
生成的程式碼預設會呼叫 main
函式,那麼如果想使用其他函式怎麼辦呢?
我們可以在函式前新增 EMSCRIPTEN_KEEPALIVE
,它在 emscripten.h
檔案中有宣告,這個可以通過原始碼檢視。
下面還是舉個例子來說明。
my.html
<!doctype html> <htmllang="en-us"> <!-- 省略... --> <body> document.querySelector('.mybutton').addEventListener('click', function(){ alert('檢查控制檯'); var result = Module.ccall('sum', // name of C function null, // return type null, // argument types null); // arguments }); </script> <scriptasynctype="text/javascript"src="hello3.js"></script> </body> </html>
裡面引用了 hello3.js
並且使用 Module.ccall
呼叫了 C 函式 sum
。
hello.c
#include<stdio.h> #include<emscripten/emscripten.h> int main(int argc, char ** argv){ printf("Hello emcc\n"); } #ifdef__cplusplus extern "C" { #endif int EMSCRIPTEN_KEEPALIVE sum(){ printf("sum = %i\n", 100); return 1; } #ifdef__cplusplus } #endif
編譯 hello.c
emcc -o hello.html hello.c -O3 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']"
注意: EXTRA_EXPORTED_RUNTIME_METHODS
設定了 Module 的匯出函式,不匯出 ccall
的話,會報以下錯誤:
'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)
現在可以執行 my.html
emrun my.html
可以修改一下 sum 函式,使其帶引數,修改如下:
#include<stdio.h> #include<emscripten/emscripten.h> int main(int argc, char ** argv){ printf("Hello World emcc\n"); } #ifdef__cplusplus extern "C" { #endif int EMSCRIPTEN_KEEPALIVE sum(int a, int b){ printf("sum = %i\n", (a+b)); return 1; } #ifdef__cplusplus } #endif
需要修改 my.html
檔案,修改內容如下:
var result = Module.ccall('sum', // name of C function null, // return type ['number'], // argument types [12, 13]); // arguments
注意 argument types
和 arguments
的填寫,執行可以看到預期效果。
掃碼關注,你我就各多一個朋友~