#そういえばkahuaの永続クラスってkahuaの外からも使えるんでしょうか。
#使えるはず
#Kahuaの外からKahuaのオブジェクトデータベースをいじるツールを作ったことがあります
#まぁ使い難いですけどね
#オブジェクトの永続化とオブジェクトデータベースは、別レイヤに整理し直した方がいいんですが、まだやってません
#質問です。
#cの拡張を書くときにschemeで定義された手続をc側から呼びたいのですが、そのあたりのstubの書きかたの参考になるものはないでしょうか。
#CからSchemeを呼ぶ場合はstubは必要ありません。
#define-cprocを<procedure>で受けとってScm_ApplyRecとかを適用すればいいのかと思うんですが、ではschemeで定義した手続の引数ってどうやってもってくるのだろうかと。
#ん、どの関数を呼ぶかはわかってる、つまり引数を何個渡すかは既にわかってる、ってことではなくて?
#引数で渡されたSchemeのprocedureを呼び出したい、そのprocedureがいくつ引数を取るかはわかってない、ってことかな?
#scheme側でコールバックを定義してあって、そいつをc側から呼んであげるケースです。
#もうちょっとやりたいことを詳しく教えてください。
#呼び出すscheme関数は引数で渡されるのか、scheme変数に格納されているのか、
#など。
#BOOL cs_eventKnown(CSint **tint, int size,
char (*known)(int val, int index, CSint **tint, int size, void *extra),
void *extra);
具体的な例を出すと上記のような関数があってknownについてはschemeで定義したいのです。cs_eventKnownをgaucheから呼べるようにstubを書いて、あとはcs_eventKnownをc側で呼ぶときのknownを設定するにはどう書いたものかなと。
#ああなるほど。knownのためにちょっとしたブリッジを書いてやる必要がありますね。
#Schemeの手続きはextraに渡すことにして、
#static char known_bridge(int val, int index, CSint **tint, int size, void *extra)
{
ScmObj proc = SCM_OBJ(extra);
ScmObj sval = Scm_MakeInteger(val);
ScmObj sindex = Scm_MakeInteger(val);
ScmObj stint = ... tint を適当に変換 ...;
ScmObj r = Scm_ApplyRec(proc, SCM_LIST3(sval, sindex, stint));
戻り値rをチェックして、charへ変換してreturn
}
#こういうknown_bridgeをknownに渡してやります。
#ちなみにScheme側から見たcs_eventKnownはextraパラメータを取らないようにします。
#(define-cproc cs-event-known (stint known) ::<boolean>
(let* ([tint::CSint**] [size::int])
;; stintからtintへ変換
(return (cs_eventKnown tint size known_bridge known))))
#こんなかんじ。CSint**はScheme側でリストかベクタで表現するのが良いでしょう。
#あ、それと、cs-event-knownに渡したクロージャへのポインタはScheme側から見えなくなるので、他にそのクロージャへの参照が無いとGCされちゃう可能性があります。なので呼び出し側でかならずグローバルに束縛しておくか、stub内でグローバルな参照を持っておくかする必要があります。
#具体例のほうでknownとcs_eventKnownの両方でextraが書かれているのをコピペしちゃったんで説明していただいたのにも関わらず混乱しているかもしれないんですが、
#extraはcs_eventKnownに渡したやつがそのままknownへ渡されるのかなと思いましたが(定石なので)、そうではない?
#そのままknownに渡される、であっています。