FFIの構造体アクセサ生成戦略

nmoshもpffiでないちゃんとした拡張インターフェースをそろそろ備えないと不味いので諸々準備中。
現状、nmoshのwx binding等外部ライブラリを使用する"プラグイン"は、すべてCのグルーコードを通して実装している。これは不便で面倒なので、本来のmosh FFIや他所のSchemeFFIPythonのCtypesのように、ホスト言語の関数宣言を直接呼び出せるタイプのFFIが必要とされている。
(もっとも、グルーコードを全廃できるとも考えていない。C++のABIを実装するのは地味に面倒 - MSVCとgccの少なくとも2つは実装する必要があり、MSVCに至ってはDebug/Relaseで互換がない - で、あまりリターンも無さそうなため。)
関数の呼び出しや、基本的なパラメタの受け渡しに関しては、グルーコードと実際の関数に大した違いは無いので大きな問題は無い。
問題は、構造体のアクセスをどう提供するかというポイントになる。

アクセサ生成戦略

構造体のアクセサをどうやって生成するかには様々な戦略が考えられる。

  • C言語の構造体配置ルールを実装する

よく利用されているのは、define-ftypeのようなstruct/配列定義用プリミティブを用意して、FFIバインディングの一貫として書いてもらう方式。( http://www.scheme.com/csug8/foreign.html#./foreign:h5 )
これは面倒だが効果は高い。
ただし、この方式はマクロによる抽象に耐えられない。つまり、C APIがCマクロに依存したアクセサのみ提供している場合は、マクロに相当する動作を手で実装することになる。

過去にAndy Wingoが言及している( http://wingolog.org/archives/2012/06/19/dltool-mines-dwarf )がこれを実装した処理系は知らない。
nmoshでも過去に試作したことは有るが、上手く行かなかった。Win32のサポートが面倒で、DWARFは常に生成されることが保証されているわけではなく、コンパイラのDWARF生成はたまにバグっていて、マクロによる抽象に耐えられない。
補完的なソリューションとしては非常に有望で、どこかのタイミングで実装する必要はありそう。

  • アクセスコードの生成

最初の配置ルール実装ににたアプローチだが、構造体の要素を記述することで、そこのオフセットとサイズを出力するCソースコードを生成してバインディングに含めてしまう。
手元の別プロジェクトでこのアプローチを取っていて、まずまずの結果を得ている。nmoshの場合、ダイナミックバインディング(late binding)に対する需要は殆ど無いので、このアプローチで十分な成果を得られるが、世間的にはダイナミックバインディングに耐えられないこの手法は採用されづらいだろう。