Gauche:FFIと型表現

Gauche:FFIと型表現

Shiro(2026/01/15 04:55:16 UTC): 再訪。以前書いた時より型については少し整理が進んだ。

Gaucheレベルで見える型:

(stub typeについてはgenstubの中でしか扱われないので、Gaucheレベルでは見えない)。

さて、FFIでのやりとりにおいて、単純な型は<native-type>がそのまま使える。複合型はどう扱うべきだろうか。

これらも<native-type>のサブタイプにしてしまうというのがひとつの方法。GaucheのインスタンスとしてはForeignPointerがあって、それが単純型か、Cの関数か、集合型を指す。<native-type>の型情報はForeignPointerのattributeに持たせる。

利点は

もうひとつの方法は、複合型についてはGaucheのクラスにしてしまうというもの。そうすると Gaucheレベルでmakeができる。

利点は

前者の方法だと、Gauche側から触る時は常に1段間接的に色々やる感じになる。例えばforeign functionから受け取った構造体をGauche側であたかもGaucheのオブジェクトのようにスロットアクセスしたかったら、ラッパークラスを作ってvirtual slotで要素アクセサを呼び出すとか。

ただ、foreign objectはライフサイクルが違ったりするから、明確に分けてた方が混乱が少ないという 考え方もできる。

2026/01/15 07:36:26 UTC: FFIデータ型として、複合型に埋め込まれた複合型と、複合型に含まれるポインタから指される複合型を区別する必要がある。 (e.g. struct { struct { ... } embed; } outer; vs. struct { struct { ... } *pointed; } outer;. Gaucheのレイヤでは複合型はScmObjから間接参照されることになるので、outerからembedを取り出した 場合もGaucheのインスタンスは「embedへのポインタ」を保持していることになる。 ならば、pointedを取り出した場合は「native pointerオブジェクトへのポインタ」を保持する インスタンスになるべきか。

なんてことを考えると、全部ForeignPointerで保持してnative型情報で区別する(embedは <native-struct>、pointedは<native-pointer struct>を型として持ち、 値はどちらもinner structのアドレスを保持する) 方が扱いやすそうだな。


Shiro(2021/05/03 08:43:27 UTC): Gauche内でCの型表現に関係する箇所がいくつかあるんだけど、必要に迫られてアドホックにやってるのでバラバラ。FFI導入を機に整理したい。

今あるコンポーネント

Stub type

define-cprocの引数と戻り値で使う ::<int> など。これはSchemeとCのブリッジの役割も担っている。

CiSE type

CiSEでCの型を表記する表現。::long とか ::(const char*) とか。

ftype

バイナリデータを扱うために書きかけになってるもの。

C parsed type representation

lang.c でCコードをパーズする際の型情報の表現。

Foreign pointer

実行時に外部オブジェクトへのポインタを扱う仕組みだが、attributeに型情報を載せることは可。

今のところ、外部ライブラリごとにカスタムでインタフェースをCで書いてるので、 汎用的に型情報をメタに扱う仕組みはない。

Native call

ネイティブ関数を呼び出す低レベルAPI

FFIで必要なもの

ftypeを軸にするのが良さそう。

ここまでftypeが重要ならコアに組み込むべきか。

More ...