Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
EmscriptenでC/C++アプリをWASM化してブラウザで動かしてみた
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
AGAWA Koji
June 12, 2024
Programming
660
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
EmscriptenでC/C++アプリをWASM化してブラウザで動かしてみた
AGAWA Koji
June 12, 2024
More Decks by AGAWA Koji
See All by AGAWA Koji
Software Architecture in an AI-Driven World
atty303
79
47k
PipeCDプラグインへの期待 / Anticipating PipeCD Plugins
atty303
0
120
良いソフトウェアとコードレビュー / Good software and code review
atty303
38
18k
Scala + Caliban で作るGraphQL バックエンド / Making GraphQL Backend with Scala + Caliban
atty303
0
600
Scala.jsとAndroidでドメイン層を共有しよう / Scala.js and Android
atty303
0
820
もう一つのビルドツール mill で作る Docker イメージ / Build docker image with mill the yet another build tool
atty303
2
2.6k
Case of Ad Delivery System is Implemented by Scala and DDD
atty303
4
3.7k
ログのメトリックを取ってみる話
atty303
0
1k
ADC2016: Axion meets HashiCorp
atty303
0
840
Other Decks in Programming
See All in Programming
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
120
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
720
Contextとはなにか
chiroruxx
1
350
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.2k
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.4k
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
860
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
890
AI 輔助遺留系統現代化的經驗分享
jame2408
1
900
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
Agentic UI
manfredsteyer
PRO
0
180
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Paper Plane (Part 1)
katiecoart
PRO
0
9.2k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
210
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
200
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
From π to Pie charts
rasagy
0
220
Thoughts on Productivity
jonyablonski
76
5.2k
30 Presentation Tips
portentint
PRO
1
330
Transcript
Emscriptenで C/C++アプリを WASM化してブラウザで動 かしてみた Koji AGAWA @atty303
Koji AGAWA @atty303 ソフトウェアエンジニア AI事業本部 ミライネージ 普段は Scala書いてます (10年弱 )
趣味で Rust書いてます (半年 ) #times_atty303
今回のターゲットアプリケーション
デスクトップ版
Web版
7日で 7000Visitsぐらい
PoBのアーキテクチャ
100% Lua ! Luaは、軽量で柔軟なスクリプト言語であり、組み込み用途やゲーム開発に広く使用され ている
Host Adapter 例えば描画に関係する関数はこれだけ GetScreenSize SetDrawLayer SetViewport SetDrawColor DrawImage DrawImageQuad DrawString
DrawStringWidth DrawStringCursorIndex
Luaをなんとかブラウザで動かせれば PoBのブラウザ版が作れそう Luaのオリジナル実装は C言語 他の言語( JSや Rust)での実装もあったが互換性に不安あり オリジナル実装をブラウザで動かしたい!
Compile your existing projects written in C or C++ —
or any language that uses LLVM — to browsers.
Emscriptenとは? LLVMをベースにしたコンパイラツールチェイン C/C++コードを WASMに変換する WASM黎明期からあるツールだがまだ開発が続いている Unityの WebGLエキスポートなどでも使われている
WebAssembly(WASM)とは? 主要なブラウザでサポートされる新しめの言語?ランタイム? 高速( GCがない!) JSと相互運用が可能
Emscriptenの使い方のイメージ 普通の CMakeでのビルド cd build cmake .. ninja Emscriptenによる CMakeでのビルド
cd build emcmake cmake .. ninja
Cと JSの相互作用
EM_ASM_JS / C → JS static int DrawStringWidth(lua_State *L) {
int n = lua_gettop(L); assert(n >= 3); assert(lua_isnumber(L, 1)); assert(lua_isstring(L, 2)); assert(lua_isstring(L, 3)); int height = lua_tointeger(L, 1); int font = luaL_checkoption(L, 2, "FIXED", fontMap); const char *text = lua_tostring(L, 3); int width = EM_ASM_INT({ return Module.getStringWidth($0, $1, UTF8ToString($2)); }, height, font, text); lua_pushinteger(L, width); return 1; } EM_ASM_JSマクロでインラインで JSが書ける
Asyncify EM_ASYNC_JS(int, paste, (), { var text = await Module.paste();
var lengthBytes = lengthBytesUTF8(text) + 1; var stringOnWasmHeap = Module._malloc(lengthBytes); stringToUTF8(text, stringOnWasmHeap, lengthBytes); return stringOnWasmHeap; }); static int Paste(lua_State *L) { const char *text = (const char *)paste(); lua_pushlstring(L, text, strlen(text)); free((void *)text); return 1; } Cから同期的に JSの Promiseを解決できる
cwrap / JS → C const onFrame = module.cwrap("on_frame", "number",
[], { async: true }); onFrame(); EMSCRIPTEN_KEEPALIVE int on_frame() { lua_State *L = GL; draw_begin(); void *buffer; size_t size; draw_get_buffer(&buffer, &size); EM_ASM({ Module.drawCommit($0, $1); }, buffer, size); draw_end(); return 0; }
WASMヒープ const wasmMemory = new WebAssembly.Memory(); const HEAPU8 = new
Uint8Array(wasmMemory.buffer); WASMのヒープは JSから見ると単なる ArrayBuffer Emscriptenでは HEAPU8などの TypedArrayが公開されている JSで mallocして Cで freeなどもできる
C/C++ ←→ JS のやりとりとメモリ表現がわかればあと はなんとかなった
高速化のために C/C++( WASM)から細かく JSの関数を呼ぶとそれなりに遅い なるべくそれぞれのランタイムに閉じる時間を長くする 描画関数は Cの世界でバッファに貯めて、フレーム終了時にまとめて JSへ転送
苦労するところ メモリ管理を間違えると例外が出る Cのメモリ破壊と同じく例外から原因が分からない デバッグビルド+サニタイザでパフォーマンスを犠牲にある程度デバッグできる
雑感 Emscripten+ WASMはかなり実用的 既存の C/C++コードの実行プラットフォームを広げたいときの選択肢としてアリ 新規で作る時は Rustなど WASMをネイティブサポートしている言語を使うほうが良いと 思う どちらにせよ昨今の
GCあり言語ほど楽ではないので覚悟は必要 WasmGCが実用レベルになってきているようなので GCあり言語から利用するのが一番 楽そう