--- title: "Bun の C Compile を試してみた" date: '2024-10-13' isPublished: true lang: 'ja' --- # はじめに 先日、Bun が C Compiler を搭載し、JS と C の相互変換が簡単にできるようになったということで、試してみました。 https://bun.sh/blog/compile-and-run-c-in-js#bun-ffi-is-low-overhead # migemo 題材を探していたところ、エンジニアの楽園のヌコ様から、`cmigemo`を試してみてはどうかという提案をいただきました。 ![0.png](./0.png) てなわけでやっていきます! > [!NOTE] > ちなみに、一番苦労したのは `cmigemo` で動く辞書の入手でした。 > READMEの方法のコマンドは古いものが多く、結局KoRoNさんから辞書ファイルを共有していただいて、それを使いました。 > [!NOTE] > migemo とは、日本語のローマ字を入力すると、それにマッチする日本語を検索するためのライブラリです。 > `cmigemo` は、migemo の C 言語版です。 > > 詳しくは、以下のリンクを参照してください。 > https://www.kaoriya.net/software/cmigemo/ # bun-cmigemo 以下のレポジトリに、`cmigemo` を使ったサンプルプログラムを置いています。 https://github.com/ryoppippi/bun-cmigemo また、npmにも公開しています。 https://www.npmjs.com/package/bun-cmigemo bunを使えば事前コンパイルが必要ないので、なんと、Cのファイルをそのままnpmに上げています。 ![1.png](./1.png) # 使い方 辞書ファイルが手元にあれば、 ```sh bun i bun-cmigemo bun pm trust bun-cmigemo # cmigemoのコードをpostinstallで落としてくるので、許可が必要 ``` でインストール後、 ```js import { Migemo } from 'bun-cmigemo'; const dictPath = '/absolute/path/to/dict'; { using migemo = new Migemo(dictPath); migemo.query(query, s => console.log(s)); } ``` で、`cmigemo` を使うことができます。 また、Hono を使った簡単なサンプルも置いています。 https://github.com/ryoppippi/bun-cmigemo/blob/d7e28a23e874c2f1a1a74108ed9227dc73308ebe/app/index.tsx ![2.gif](./2.gif) # 簡単なコード解説 本当に簡単にCのコードが呼び出せたので、あまり解説することはありませんが、一応。 まず、`cmigemo` の関数をラップした関数をCで書きます。 https://github.com/ryoppippi/bun-cmigemo/blob/d7e28a23e874c2f1a1a74108ed9227dc73308ebe/lib/main.c 今回は3つの関数を定義しました。 - `migemoOpen`: 辞書ファイルを開いて `migemo` インスタンスを作成する - `migemoQuery`: 引数として、`migemo` インスタンス、クエリ、callback 関数を受け取り、クエリにマッチする文字列を callback 関数に渡す。callback 関数実行後、結果を free する。 - `migemoClose`: `migemo` インスタンスを free する。 次に、上で定義した関数を呼び出すために、`bun cc` 関数を使って定義を書いていきます。 https://github.com/ryoppippi/bun-cmigemo/blob/d7e28a23e874c2f1a1a74108ed9227dc73308ebe/lib/index.ts#L12-L37 やはり面白いのは JS の callback 関数を C に渡せるところですね。 文字列を直接戻り値として渡してもよかったのですが、メモリの確保や解放が面倒だったので、今回は callback 関数を使いました。 これで終わりでも良いのですが、ユーザーがいちいち `migemoOpen` と `migemoClose` を呼び出すのは面倒なので、これらをいい感じにラップして、`Migemo` クラスを作りました。 https://github.com/ryoppippi/bun-cmigemo/blob/d7e28a23e874c2f1a1a74108ed9227dc73308ebe/lib/index.ts#L54-L90 ポイントは、 - `Migemo` クラスを `using migemo = new Migemo('./migemo-dict');` でインスタンス化することで、scope から外れると自動的に `migemoClose` が呼ばれる - `migemo.query` で クエリと callback 関数を渡すことで、`migemoQuery` が呼ばれる (結果は callback 関数に渡され、callback 関数が終了した後にメモリが解放される) > [!NOTE] > `bun cc` のドキュメントはこちら: > https://bun.sh/docs/api/cc # おわりに 今回は、`cmigemo` を使ってみましたが、他にもいろいろなライブラリを使ってみたいと思います。 楽しいですね!