概要
- Rubik’s cube最適化ソルバー をWebAssembly化した経験談の解説。
- CコードをEmscriptenでWASMに変換 し、JavaScript・HTMLフロントエンドと連携。
- WASMの仕組みや制約、ライブラリ化、JavaScriptとの連携方法を紹介。
- サンプルコードやセットアップ手順 を具体的に解説。
- WebAssembly入門者やC/C++開発者 向けの実践的なガイド。
はじめに
- Rubik’s cube最適化ソルバー をWebアプリ化した体験談。
- Cコード(マルチスレッド・SIMD・コールバック関数含む) をEmscriptenでWebAssembly(WASM)に変換。
- JavaScript・HTMLの最小限のフロントエンド実装 による構成。
- WebAssemblyのメリット は、Webブラウザ上で ネイティブに近い性能 を発揮できる点。
- C/C++開発者が既存コードをWeb移植 する際の具体的な手順解説。
セットアップ
- チュートリアル用サンプルコード はgitリポジトリ(git.tronto.net、GitHub)で公開。
- 必要なもの:
- Emscripten(Node.js含む) のインストール(公式サイト参照)。
- Webサーバ (例:darkhttpd、Pythonのhttp.server)。
- Linux/UNIX環境推奨、WindowsはWSLや調整で対応可能。
- サンプルコードは各ディレクトリに格納、コマンドやビルドスクリプトも用意。
Hello world
-
最初の例:C言語のHello World プログラムを用意。
#include <stdio.h> int main() { printf("Hello, web!\n"); } -
emcc -o index.html hello.c でビルド、 index.html/index.wasm/index.js が生成される。
-
Webサーバ(darkhttpd .) を起動し、 localhost:8080 で動作確認。
-
生成物の説明 :
- index.html :Emscripten標準テンプレートのWebページ。
- index.wasm :WebAssemblyバイトコード本体。
- index.js :WASMをWebブラウザで動かすためのJavaScriptグルーコード。
-
Node.jsでも実行可能 (node index.js)、ただし後述の例では差異が発生する場合あり。
-
-sSTANDALONE_WASM でWASM単体生成も可能だが、基本的には JSグルーコード必須。
Intermezzo I: WebAssemblyとは何か?
- WebAssembly(WASM) はWebブラウザ内で動作する 低レベル仮想マシン用言語。
- JavaScriptより高性能なWebアプリ実現 を目的とし、 コンパクトなバイトコード & スタックマシン 設計。
- 主要ブラウザで2017年頃からサポート、Emscriptenは2011年登場(当初はasm.js変換)。
- WASMはテキスト表現も存在 し、直接記述・アセンブルも可能。
- 32bitアーキテクチャ制限 (4GBメモリ上限、ポインタ32bit)、 WASM64 (64bit)は一部ブラウザでサポート開始。
- ローカル実行にはWasmtime等も利用可能。
ライブラリのビルド
-
C関数をWASMライブラリ化 し、JavaScriptから呼び出し。
-
例:multiply関数
// library.c int multiply(int a, int b) { return a * b; } -
emcc -o library.js library.c でビルド、 library.js/library.wasm 生成。
-
Node.jsからの呼び出し 例:
var library = require("./library.js"); const result = library.multiply(6, 7); console.log("The answer is " + result); -
関数名にアンダースコア(_)が付与 されるため、 library._multiply() で呼び出し。
-
-sEXPORTED_FUNCTIONS でエクスポート関数指定が必要:
emcc -sEXPORTED_FUNCTION=_multiply -o library.js library.c -
ランタイム初期化待ちが必要 (非同期処理):
var library = require("./library.js"); library.onRuntimeInitialized = () => { const result = library._multiply(6, 7); console.log("The answer is " + result); }; -
01_libraryディレクトリにサンプルコードあり。
Intermezzo II: JavaScriptとDOM
-
JavaScriptからHTML要素を操作 するには DOM(Document Object Model) を利用。
-
例:HTMLのパラグラフ要素を変更
<p id="myParagraph">Hello!</p>var paragraph = document.getElementById("myParagraph"); paragraph.innerText = "New text!"; -
IDで要素を取得し、プロパティを更新 する手法。
-
ボタンとの連携やイベント処理 など、インタラクティブなWebページ構築に必須。
以降の内容(ボタン例、より複雑なDOM操作、ライブラリのモジュール化、マルチスレッド、Web Workers等)は次のセクションや記事タイトルで順次まとめていきます。必要に応じて指示ください。