WebAssembly-「HelloWorld」
この章では、Cで簡単なプログラムを作成し、それを.wasmに変換し、ブラウザーで同じように実行して、「HelloWorld」というテキストを取得します。
Cプログラムを.wasmに変換し、.htmlファイル内の.wasmを利用するwasmエクスプローラーツールを利用します。
で利用可能なWasmエクスプローラーツール https://mbebenita.github.io/WasmExplorer/ looks as follows −
使用するCコードは次のとおりです。
#include <stdio.h>
char *c_hello() {
return "Hello World";
}
以下に示すように、wasmexplorerの最初のブロックをCコードで更新します-
以下に示すように、COMPILEボタンをクリックして、WASM、WAT、およびFirefox x86Webアセンブリにコンパイルします。
ダウンロードを使用して.wasmファイルを取得し、名前を付けて保存します firstprog.wasm。
以下に示すように、firstprog.htmlという.htmlファイルを作成します-
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Hello World</title>
</head>
<body>
<div id="textcontent"></div>
<script type="text/javascript">
//Your code from webassembly here
</script>
</body>
</html>
ここで、firstprog.wasmを使用して、C関数c_hello()からhelloworldを読み取ります。
ステップ1
fetch()apiを使用して、firstprog.wasmコードを読み取ります。
ステップ2
.wasmコードは、を使用してarraybufferに変換する必要があります ArrayBuffer。ArrayBufferオブジェクトは、固定長のバイナリデータバッファを返します。
これまでのコードは次のようになります-
<script type="text/javascript">
fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer())
</script>
ステップ3
ArrayBufferからのバイトは、を使用してモジュールにコンパイルする必要があります WebAssembly.compile(buffer) 関数。
コードは次のようになります-
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
</script>
ステップ4
モジュールを取得するには、以下に示すようにwebassembly.instanceコンストラクターを呼び出す必要があります-
<script type="text/javascript">
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module) })
</script>
ステップ5
インスタンスをコンソールして、ブラウザで詳細を確認しましょう。
<script type="text/javascript">
fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod)) .then(module => {
return new WebAssembly.Instance(module)
})
.then(instance => {
console.log(instance);
});
</script>
console.logの詳細を以下に示します-
関数c_hello()から文字列「HelloWorld」を取得するには、javascriptにコードを追加する必要があります。
まず、以下に示すようにメモリバッファの詳細を取得します-
let buffer = instance.exports.memory.buffer;;
バッファ値から値を読み取ることができるように、バッファ値を型付き配列に変換する必要があります。バッファーには、文字列HelloWorldが含まれています。
型付きに変換するには、以下に示すようにコンストラクターUint8Arrayを呼び出します-
let buffer = new Uint8Array(instance.exports.memory.buffer);
これで、forループでバッファーから値を読み取ることができます。
以下に示すように作成した関数を呼び出して、バッファーを読み取るための開始点を取得しましょう。
let test = instance.exports.c_hello();
これで、テスト変数に文字列を読み取るための開始点があります。WebAssemblyには文字列値用のものはなく、すべてが整数として格納されます。
したがって、バッファから値を読み取ると、それらは整数値になり、JavaScriptのfromCharCode()を使用して文字列に変換する必要があります。
コードは次のとおりです-
let mytext = "";
for (let i=test; buffer[i]; i++){
mytext += String.fromCharCode(buffer[i]);
}
これで、mytextをコンソールすると、「HelloWorld」という文字列が表示されます。
例
完全なコードは次のとおりです-
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly Add Function</title>
<style>
div {
font-size : 30px; text-align : center; color:orange;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
fetch("firstprog.wasm")
.then(bytes => bytes.arrayBuffer())
.then(mod => WebAssembly.compile(mod))
.then(module => {return new WebAssembly.Instance(module)})
.then(instance => {
console.log(instance);
let buffer = new Uint8Array(instance.exports.memory.buffer);
let test = instance.exports.c_hello();
let mytext = "";
for (let i=test; buffer[i]; i++) {
mytext += String.fromCharCode(buffer[i]);
}
console.log(mytext); document.getElementById("textcontent").innerHTML = mytext;
});
</script>
</body>
</html>
divを追加し、コンテンツをdivに追加したので、文字列がブラウザに表示されます。
出力
出力は以下に記載されています-