🐇

Bun で JavaScript からC言語を実行する

2024/10/15に公開

はじめに

JavaScriptはウェブ開発で広く使われていますが、場合によっては低レベルの処理や高性能な計算が必要になることがあります。そんなときに役立つのが、C言語との連携です。Bunは高速なJavaScriptランタイムであり、FFI(Foreign Function Interface)をサポートしています。本記事では、JavaScriptプログラマ向けにBunを使ってC言語のコードを実行する方法を解説します。

FFIとは

FFI(Foreign Function Interface)は、あるプログラミング言語から別の言語で書かれた関数やライブラリを呼び出すための仕組みです。これにより、JavaScriptからC言語の関数を直接呼び出すことができます。FFIを使うことで、既存のCライブラリを活用したり、パフォーマンスを向上させたりすることが可能になります。

BunのFFIを使うメリット

  • 高性能: C言語で書かれたコードは、JavaScriptよりも高速に実行されることが多いです。
  • ライブラリの活用: 豊富なC言語のライブラリをJavaScriptから利用できます。
  • システムリソースへのアクセス: 低レベルのシステム操作が可能になります。

環境設定

Bunのインストール

Bunをまだインストールしていない場合は、以下のコマンドでインストールします。

curl -fsSL https://bun.sh/install | bash

必要なツールのインストール

まずは、Cコンパイラを準備してください。macOSの場合はXcode Command Line Tools、Linuxの場合はgccclangをインストールしてください。

C言語のコードを書く

では、シンプルなC言語の関数を作成します。例として、2つの整数を加算する関数を書いてみましょう。

add.c

// add.c
int add(int a, int b) {
    return a + b;
}

このファイルをコンパイルして共有ライブラリを作成します。

コンパイルコマンド

macOSの場合:

cc -shared -o add.dylib -fPIC add.c

Linuxの場合:

cc -shared -o add.so -fPIC add.c

これで共有ライブラリが作成されました。

BunでCコードを呼び出す

次に、BunのFFIを使ってこの関数を呼び出します。

JavaScriptコードを書く

// index.js
const { dlopen, FFIType } = require('bun:ffi');
const path = require('path');

// ライブラリのパスを指定
const libPath = path.resolve('./add.so'); // macOSの場合は './add.dylib'

// 関数シグネチャを定義
const symbols = {
  add: {
    args: [FFIType.int, FFIType.int],
    returns: FFIType.int,
  },
};

// ライブラリをロード
const lib = dlopen(libPath, symbols);

// 関数を呼び出し
const result = lib.symbols.add(5, 7);
console.log(`結果: ${result}`); // 結果: 12

コードの解説

  • dlopenFFITypeのインポート: bun:ffiからこれらをインポートします。
  • ライブラリのパス指定: pathモジュールを使ってライブラリのパスを指定します。
  • 関数シグネチャの定義: C関数の引数と戻り値の型を指定します。
  • ライブラリのロード: dlopenを使ってライブラリをロードします。
  • 関数の呼び出し: lib.symbols.addでC関数を呼び出します。

スクリプトの実行

bun index.js

実行結果:

結果: 12

まとめ

BunのFFIを使うことで、JavaScriptから直接C言語の関数を呼び出すことができます。これにより、パフォーマンスの向上や既存のCライブラリの活用が可能になります。ぜひ、自分のプロジェクトで試してみてください。

Discussion