🐈
Bun の C Compile を試してみた
はじめに
先日、Bun が C Compiler を搭載し、JS と C の相互変換が簡単にできるようになったということで、試してみました。
migemo
題材を探していたところ、エンジニアの楽園のヌコ様から、cmigemo
を試してみてはどうかという提案をいただきました。
てなわけでやっていきます!
bun-cmigemo
以下のレポジトリに、cmigemo
を使ったサンプルプログラムを置いています。
また、npmにも公開しています。
bunを使えば事前コンパイルが必要ないので、なんと、Cのファイルをそのままnpmに上げています。
使い方
辞書ファイルが手元にあれば、
bun i bun-cmigemo
bun pm trust bun-cmigemo # cmigemoのコードをpostinstallで落としてくるので、許可が必要
でインストール後、
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 を使った簡単なサンプルも置いています。
簡単なコード解説
本当に簡単にCのコードが呼び出せたので、あまり解説することはありませんが、一応。
まず、cmigemo
の関数をラップした関数をCで書きます。
今回は3つの関数を定義しました。
-
migemoOpen
: 辞書ファイルを開いてmigemo
インスタンスを作成する -
migemoQuery
: 引数として、migemo
インスタンス、クエリ、callback 関数を受け取り、クエリにマッチする文字列を callback 関数に渡す。callback 関数実行後、結果を free する。 -
migemoClose
:migemo
インスタンスを free する。
次に、上で定義した関数を呼び出すために、bun cc
関数を使って定義を書いていきます。
やはり面白いのは JS の callback 関数を C に渡せるところですね。
文字列を直接戻り値として渡してもよかったのですが、メモリの確保や解放が面倒だったので、今回は callback 関数を使いました。
これで終わりでも良いのですが、ユーザーがいちいち migemoOpen
と migemoClose
を呼び出すのは面倒なので、これらをいい感じにラップして、Migemo
クラスを作りました。
ポイントは、
-
Migemo
クラスをusing migemo = new Migemo('./migemo-dict');
でインスタンス化することで、scope から外れると自動的にmigemoClose
が呼ばれる -
migemo.query
で クエリと callback 関数を渡すことで、migemoQuery
が呼ばれる (結果は callback 関数に渡され、callback 関数が終了した後にメモリが解放される)
おわりに
今回は、cmigemo
を使ってみましたが、他にもいろいろなライブラリを使ってみたいと思います。
楽しいですね!
Discussion
補足です!
cmigemoのライブラリの作法として、「結果を文字列として返し、その文字列のはいっているメモリは解放しないといけない」という前提があります。なので、本文でたびたび「メモリの解放」という文言が出てきますが、それはcmigemoにおけるメモリ解放を指しています。
また加えて、実際の実装ではJavaScriptのcallback関数に対するメモリの解放も行っているのですが、本文中では触れていません。コードとドキュメントを参照してください。