In message <E11njSs-0006V8-00 / ev.netlab.co.jp>
matz / netlab.co.jp writes:

> Data_Wrap_Structからrb_define_constまでの間にGCが発生すると、
> 回収されちゃいます。rb_define_constまで届けばもう問題は無い
> んですけど。GCはオブジェクトの割り当てにともなって発生する可
> 能性がありますから、問題が発生する危険は十分あります。

結局グローバル変数とローカル変数両方使うようにしてごまかしました.以下
のような感じ:

    extern qpi[];
    extern qeul[];
    
    QELT *qinf, *qninf;
    
    Init_qfloat()
    {
        QELT *pi, *eul, *inf, *ninf;
        VALUE PI, EUL, INF, NINF;
            :
        qinf = inf = ALLOC_N(QELT, NQ);
            :
        INF = Data_Wrap_Struct(rb_cQfloat, 0, free, inf);
            :
        rb_define_const(rb_cQfloat, "INF", INF);
    }


最初の疑問,「Data_Wrap_Struct にグローバル変数を渡してはいけない?」に
ついては,

    ruby インタプリタは終了時に rb_gc_call_finalizer_at_exit を呼び,
    この時 Data_Wrap_Struct の第三引数で指定した finalize function を
    呼び出す.

    最初にやっていたように「グローバル変数の配列をラップするのに盲目的
    に finalize function に free を指定」なんて事をすると,「配列に対
    して free しようとする」事になり大層よろしくない :-P

ということでよろしいでしょうか.


ソースはそうのように見える.ついでに free ではなく 0 を渡せば最初のコー
ドでも良かったような気もする.つまり,

    QELT qinf[NQ], qninf[NQ];
    
    Init_qfloat()
    {
        VALUE INF = Data_Wrap_Struct(rb_cQfloat, 0, 0, qinf);
            :
        rb_define_const(rb_cQfloat, "INF", INF);
    }

こんな形.

# こっちの方が変な変数が増えなくていいかな?


-- 
柳川和久 @ 東大阪市 . 大阪府                              November 17, 1999
Dreams come true --- excepting yours.