EmscriptenでJSとCで相互にデータをやり取りする
Emscripten で JavaScript の世界と C の世界でデータをやり取りする方法をメモ (with ccall/cwrap)。
C や C++ 側で必要なこと Emscripten でコンパイルすると、main から到達できないコードは dead code elimination でサクサク消されちゃうので 関数に EMSCRIPTEN_KEEPALIVE を付けて消されないようにしておく必要がある (EMSCRIPTEN_KEEPALIVE 自体は __attribute__((used)) に展開されるっぽい。環境によるとは思うけど)。
コンパイルは
emcc -s WASM=1 -s NO_EXIT_RUNTIME=1 -s EXPORTED_RUNTIME_METHODS="['ccall']" -o index.html main.cc とかで。NO_EXIT_RUNTIME にしておくことで、 main を実行したあとランタイムを止めるというデフォルトの挙動を変更できる。 ExPORTED_RUNTIME_METHODS に cwrap とかを入れておくと cwrap から使えるようになる。
ccall や cwrap で関数を呼び出すときの基本的な方法 Module.cwrap('hoge', 'string', 'number')(5); みたいな感じで C の関数を呼び出せるが、問題は引数と戻り値のところに何を入れるかということになる。