FFI における構造体問題

Scheme から C の関数を呼び出せるとなると MySQL に接続してみたくなる。しかしながら libmysqlclient の mysql_init は

MYSQL *	STDCALL mysql_init(MYSQL *mysql);

MYSQL 構造体を呼び出し側で割り当てて渡してあげないといけない。(正確には渡すのはポインタ)


しかし Scheme 側からこの構造体を割り当てるのは少し難しい。Scheme 側から MYSQL 構造体のの詳細が分からないのだ。構造体メンバは、構造体のサイズが分からないと割り当てられない。
MYSQL 構造体のメンバに Scheme が直接アクセスする事はないと思うので、ここでは構造体のサイズが分かれば良い。


4つほど方法を思いつく。

  • FFI のコードを書くユーザーが MYSQL のサイズを計ってコードに埋め込む
    • (let ([MYSQL (make-bytevector 964)]) ...) こんな感じ。
    • サイズは printf("%d\n", sizeof(MYSQL)) なコードを別に走らせてみれば良い。
    • 問題点:構造体のサイズはプラットフォーム依存。32bit/64bit でも違うし。OSでも違う。
    • 問題点に対する解決方法:多めにサイズを取る
  • ユーザーに構造体メンバを列挙させて、FFI システムがそのプラットフォームでの構造体サイズを計算する
    • 面倒だし間違えるかも?
    • 構造体が構造体を含んでいると必要な定義が増える
  • どうしても必要な部分は C で書く。共有ライブラリにして動的にロードする
    • MYSQL* my_mysql_init() のような関数を書くとか。
    • Perl の DBD::mysql はこの方式
  • FFI 用の洗練されたインターフェースを持っているライブラリのみを対象とする
    • よく使われるライブラリは外部から呼びやすくなっているはずだ。
    • 実は mysql_init は NULL を渡すと MYSQL オブジェクトを中で割り当ててくれる。これで解決


もっと良い方法あったら教えてください。