WebAssembly - C言語との連携

WebAssemblyとCへの導入

こんにちは、未来のプログラミング魔法使いさんたち!今日は、WebAssemblyとCの世界に一緒に飛び込んでいきます。あなたの近所の親切なコンピュータサイエンスの先生として、私が初めてコードの魔法を発見したときと同じような熱意でこの冒険を案内します。しっかりと準備して、一緒に飛び込んでみましょう!

WebAssembly - Working with C

WebAssemblyとは?

WebAssembly、またはWasmと略して、あなたのウェブブラウザが超高速なコードを実行できる秘密の言語のようなものです。あなたのブラウザが突然スーパーパワーの獲得したかのようです - それがWebAssemblyです!C言語などの言語でコードを書き、ブラウザでほぼネイティブスピードで実行することができます。

なぜWebAssemblyとC?

あなたはおそらく、「なぜC?古い言語じゃないの?」と思っているかもしれません。しかし、私の若い弟子たち、Cはプログラミング言語の賢い祖父母のようなものです。長い間存在してきましたし、速くて効率的で、多くの既存のコードを利用できるからです。CをWebAssemblyで使用することで、この強力なツールをウェブに持ってくるのです。

環境の設定

コードを書く前に、デジタルな工作場を整備する必要があります。心配しないでください。 IKEAの家具を組み立てるよりも簡単です!

Emscriptenのインストール

Emscriptenは、CコードをWebAssemblyに変換する魔法のツールです。以下の手順でインストールします:

  1. ターミナルを開きます(怖くないですよ、テキストベースの友達です)
  2. 以下のコマンドを実行します:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

おめでとうございます!あなたのWebAssembly研究所を設置しました。

最初のWebAssemblyプログラム

簡単な「Hello, World!」プログラムから始めましょう。これがコードの初めての言葉です!

Cコードの作成

hello.cという名前のファイルを作成し、以下のコードを追加します:

#include <stdio.h>

int main() {
printf("Hello, WebAssembly World!\n");
return 0;
}

この小さなスニペットは、コンピュータに挨拶を印刷させる指示を出しています。パロットに「こんにちは」と言わせるのと同じですが、もっとクールです!

WebAssemblyへのコンパイル

次に、CコードをWebAssemblyに変換します。ターミナルで以下のコマンドを実行します:

emcc hello.c -s WASM=1 -o hello.html

このコマンドは魔法の杖を振るようなものです。hello.htmlhello.jshello.wasmという3つのファイルが生成されます。

WebAssemblyプログラムの実行

hello.htmlファイルをブラウザで開くと、「Hello, WebAssembly World!」が表示されます。おめでとうございます!あなたの最初のWebAssemblyプログラムを実行しました!

関数との連携

こんにちはを言った後、実際の作業を始めましょう。二つの数を足す関数を作成します。

シンプルな加算関数の作成

新しいファイルmath.cを作成し、以下のコードを追加します:

#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}

EMSCRIPTEN_KEEPALIVEはコンパイラに「この関数は重要だ!消さないでくれ」と言っています。

関数のコンパイル

以下のコマンドでコンパイルします:

emcc math.c -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -o math.js

これにより、math.jsmath.wasmが生成されます。

JavaScriptでの関数の使用

次に、JavaScriptでC関数を使用します。index.htmlファイルを作成します:

<!DOCTYPE html>
<html>
<head>
<title>WebAssembly Math</title>
</head>
<body>
<h1>WebAssembly Math</h1>
<p>Result: <span id="result"></span></p>
<script src="math.js"></script>
<script>
Module.onRuntimeInitialized = function() {
var result = Module._add(5, 7);
document.getElementById('result').textContent = result;
};
</script>
</body>
</html>

ブラウザでこれを開くと、5 + 7の結果が表示されます!

メモリとの連携

次に、メモリ操作を少し進めてみましょう。これは、あなたのWebAssemblyスーパーパワーのノートブックへのアクセスを提供することのようなものです。

メモリの割り当てと使用

memory.cという名前のファイルを作成し、以下のコードを追加します:

#include <emscripten.h>
#include <stdlib.h>

EMSCRIPTEN_KEEPALIVE
int* create_array(int size) {
return (int*)malloc(size * sizeof(int));
}

EMSCRIPTEN_KEEPALIVE
void fill_array(int* arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] = i * 2;
}
}

EMSCRIPTEN_KEEPALIVE
int sum_array(int* arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}

EMSCRIPTEN_KEEPALIVE
void free_array(int* arr) {
free(arr);
}

以下のコマンドでコンパイルします:

emcc memory.c -s WASM=1 -s EXPORTED_FUNCTIONS='["_create_array", "_fill_array", "_sum_array", "_free_array"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o memory.js

次に、JavaScriptでこれらの関数を使用します:

<!DOCTYPE html>
<html>
<head>
<title>WebAssembly Memory</title>
</head>
<body>
<h1>WebAssembly Memory Management</h1>
<p>Sum of array: <span id="result"></span></p>
<script src="memory.js"></script>
<script>
Module.onRuntimeInitialized = function() {
const create_array = Module.cwrap('create_array', 'number', ['number']);
const fill_array = Module.cwrap('fill_array', null, ['number', 'number']);
const sum_array = Module.cwrap('sum_array', 'number', ['number', 'number']);
const free_array = Module.cwrap('free_array', null, ['number']);

const size = 10;
const ptr = create_array(size);
fill_array(ptr, size);
const sum = sum_array(ptr, size);
free_array(ptr);

document.getElementById('result').textContent = sum;
};
</script>
</body>
</html>

この例では、メモリを割り当て、配列を填充し、合計を計算し、メモリを解放する - これら全てをJavaScriptからC関数を呼び出して行っています!

結論

おめでとうございます、C言語とWebAssemblyの世界への第一歩を踏み出しました!基本的なことをカバーし、メモリ操作まで進めました。コードを書くことは新しい言語を学ぶのと同じで、練習と忍耐が必要です。しかし、あなたが書くそれぞれのコードの行ごとに、コンピュータの言語にますます精通していくのです。

このまとめとして、私たちが学んだ主要な関数の表を以下に示します:

関数 説明
printf() コンソールにテキストを印刷 printf("Hello, World!");
malloc() メモリを割り当て int arr = (int)malloc(size * sizeof(int));
free() 割り当てられたメモリを解放 free(arr);
EMSCRIPTEN_KEEPALIVE 関数が最適化されないようにする EMSCRIPTEN_KEEPALIVE int add(int a, int b)

引き続きコードを書き、学び続けてください。プログラミングの世界では、唯一の限界はあなたの想像力です!未来の技術のスーパースターとして、ハッピーコーディングを!

Credits: Image by storyset