@ryoppippi

Bun の C Compile を試してみた

13 Oct 2024 ・ 5 min read


はじめに

先日、​Bun が​ C Compiler を​搭載し、​JS と​ C の​相互変換が​簡単に​できるようになったと​いう​ことで、​試してみました。

https://bun.sh/blog/compile-and-run-c-in-js#bun-ffi-is-low-overhead

migemo

題材を​探していた​ところ、​エンジニアの​楽園の​ヌコ様から、cmigemoを​試してみては​どうかと​いう​提案を​いただきました。

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

使い方

辞書ファイルが​手元に​あれば、

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 を​使った​簡単な​サンプルも​置いています。

https://github.com/ryoppippi/bun-cmigemo/blob/d7e28a23e874c2f1a1a74108ed9227dc73308ebe/app/index.tsx

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 を​使ってみましたが、​他にも​いろいろな​ライブラリを​使ってみたいと​思います。 楽しいですね!

comment on bluesky / twitter
CC BY-NC-SA 4.0 2022-PRESENT © ryoppippi