I set up the WebAssembly environment. What do I need to write to make it work?
As of the date of this post (August 2017), the thing that holds the most interest and promise is WebAssembly. At the moment, it already works in FireFox and Chrome, so I can't not try it. In fact, I've been gathering information about it since a month ago (July 2017), but it's been difficult and frustrating.
Eventually, the development environment will be ready.
Perhaps, just like the shift from Eclipse to AndroidStudio in Android application development, the time will come in the not-too-distant future when you can easily build a development environment and concentrate on writing code without worrying about this and that.
Set up a development environment at this time (August 2017).
https://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm
Set up a development environment in Windows 10.
Git、CMake、Visual Studio Community 2015 with Update 3
Setup as described.
Follow the tutorial.
First, I tried following the tutorial. An HTML file with various descriptions, a JS file, and a WASM file were output, and I could execute them as written. However, this is not what I want to do. I want to prepare a more compact and minimal executable file. Then I want to call the generated code with arguments and get the return value.
Stripped down to the bare minimum
The prepared C code is as follows, with main() also prepared but not used.
The name of the file is fnc.c.
#include <emscripten/emscripten.h>
int main(int argc, char ** argv) {
}
#ifdef __cplusplus
extern "C" {
#endif
int EMSCRIPTEN_KEEPALIVE fnc(int num) {
return num * num;
}
#ifdef __cplusplus
}
#endif
The command line for compilation is as follows.
emcc fnc.c -o fnc.js -O3 -s WASM=1
The following is for outputting HTML files as well.
emcc fnc.c -o fnc.html -O3 -s WASM=1 --shell-file shell_minimal.html
Please look for shell_minimal.html at the explanation site.
I tried to keep the generated HTML to a minimum. The result was as follows.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button type="button" id="run">Run</button>
<div id="result"></div>
<script>
document.getElementById('run').addEventListener('click',function(){
var result = Module.ccall('fnc','number',['number'],[7]);
document.getElementById('result').innerHTML = result;
},false);
</script>
<script async src="fnc.js"></script>
</body>
</html>
When you click on the button labeled "Run", the wasm generated by the C compilation is called and you get the result. The C function fnc is passed one argument 7 as a numerical value, and the return value is obtained as a numerical value, and it is displayed.
fnc.js is automatically generated and is usually used as is.
As shown in the code, passing 7 will return 7 squared, and if 49 is displayed, it succeeds.
About Arguments
The arguments to pass to wasm are written in the following site for the JS side.
https://kripken.github.io/emscripten-site/
Module.ccall() has four arguments, in the following order.
- Function name of C.
- Type of the return value
- Argument type (array)
- Argument values (array)
In the case of passing JSON and receiving JSON, etc., that is, passing a string and receiving a string, the C code would be as follows.
char* EMSCRIPTEN_KEEPALIVE fnc(char* json) {
return "{}";
}
JS looks like the following.
var json = '{}';
var result = Module.ccall('fnc','string',['string'],[json]);
If you want to pass a number and a string as arguments, do the following
var num = 100;
var json = '{}';
var result = Module.ccall('fnc','string',['number','string'],[num,json]);
In this case, C is written as follows.
char* EMSCRIPTEN_KEEPALIVE fnc(int num, char* json) {
return "{}";
}
Now we have the minimum structure. Now all we have to do is write the code we want to write.
EMSCRIPTEN_KEEPALIVE
The EMSCRIPTEN_KEEPALIVE in front of the C function name is to prevent the C compiler from making the function name an alias for optimization.
Caution
FireFox allows you to run local files without setting up a server, but Chrome requires you to set up a server with XAMPP or similar. I get the following error.
Fetch API cannot load ***. URL scheme must be "http" or "https" for CORS request.