0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows11 の VSCode+Emscripten で wasm によるハローワールド (14)

Last updated at Posted at 2025-10-12

すべての記事

コンパイルするスレッドの分離

UI とは異なるスレッドでコンパイルまでを実行し、メインスレッドに引き渡す。
メインスレッドでは、コンパイル済 wasm モジュールをインスタンス化し、Emscripten ランタイム・モジュールに処理を移す。
前の記事 にあるコードの一部を Worker で指定する JavaScript に分割すれば実装できる。

以下はそのファイルの一覧となる。

C:\wasm\project\11-compile-worker\.vscode\launch.json

{
    "version": "0.2.0",
    "configurations": [

        {
            "type": "chrome",
            "request": "launch",
            "name": "localhost:8080",
            "url": "http://localhost:8080/",
        }
    ]
}

C:\wasm\project\11-compile-worker\CMakePresets.json

{
  "version": 5,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "wasm-config",
      "hidden": true,
      "generator": "Ninja Multi-Config",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_CXX_STANDARD": "17",
        "CMAKE_CXX_STANDARD_REQUIRED": "ON",
        "CMAKE_CXX_EXTENSIONS": "OFF",
        "CMAKE_TOOLCHAIN_FILE": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
        "CMAKE_CONFIGURATION_TYPES": "Debug;Release"
      }
    },
    {
      "name": "wasm-config-debug",
      "inherits": "wasm-config",
      "cacheVariables": {
      }
    },
    {
      "name": "wasm-config-release",
      "inherits": "wasm-config",
      "cacheVariables": {
      }
    }
  ],
  "buildPresets": [
    {
      "name": "wasm-build-debug",
      "configurePreset": "wasm-config-debug",
      "verbose": true,
      "configuration": "Debug"
    },
    {
      "name": "wasm-build-release",
      "configurePreset": "wasm-config-release",
      "verbose": true,
      "configuration": "Release"
    }
  ]
}

C:\wasm\project\11-compile-worker\CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(11_compile_worker LANGUAGES CXX)

add_executable(11_compile_worker main.cpp)
target_link_options(11_compile_worker PRIVATE
    $<$<CONFIG:Debug>:-gsource-map -sASSERTIONS=1 -sSAFE_HEAP=1>
    "-sEXPORT_ES6=1"
)

C:\wasm\project\11-compile-worker\worker.js
fetch() で取得したバイナリをコンパイルしてメインスレッドに送信する

fetch('./build/Debug/11_compile_worker.wasm').then(response => {
    console.log('fetch done');
    WebAssembly.compileStreaming(response).then(wasmModule => {
        console.log('compile done')

        self.postMessage(wasmModule);
    });
});

C:\wasm\project\11-compile-worker\index.html
ワーカースレッドから postMessage により送信された値 (WebAssembly モジュール) を使ってインスタンス化する

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8"/>
        <script type="module">
            import Module from './build/Debug/11_compile_worker.js';
            const worker = new Worker('./worker.js');

            worker.onmessage = e => {
                console.log('on message');
                const wasmModule = e.data;

                const moduleInfo = {
                    arguments: ['compile', 'worker'],
                    instantiateWasm: async (imports, successCallback) =>
                    {
                        const wasmInstance = await WebAssembly.instantiate(wasmModule, imports);
                        console.log('instantiate');

                        successCallback(wasmInstance);
                    },
                };

                let v = 0;

                Module(moduleInfo).then(emsModule =>
                {
                    // Emscripten モジュールにより C++ の関数を呼び出す

                    v = emsModule._increment(v);
                    console.log(`return=${v}`);
                });

            };
        </script>
    </head>
    <body>
    </body>
</html>

C:\wasm\project\11-compile-worker\main.cpp

// UTF-8N CRLF
#include <emscripten.h>
#include <cstdio>

extern "C"
EMSCRIPTEN_KEEPALIVE
int increment(int v)
{
	printf("-- increment(%d)\n", v);
	return v + 1;
}

int main(int argc, char** argv)
{
	printf("C++ main(argc=%d, argv=[", argc);

	for (int i=0; i<argc; ++i)
	{
		if (i) {
			printf(",");
		}
		printf("'%s'", argv[i]);
	}

	puts("])");

	return 0;
}

// EOF

実行結果

on message
instantiate
fetch done
compile done
C++ main(argc=3, argv=['./this.program','compile','worker'])
-- increment(0)
return=1

次回 は依存関係のあるファイルの処理について試してみる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?