2

これは、私の問題を切り分けるコードです。

#include "ruby.h"
#include "stdlib.h"

typedef struct HandValues {
    double pair1;
    double pair2;
} HandValues;

static VALUE 
get_pairs_2(self) 
  VALUE self;
{

    HandValues *MadeHand = (HandValues *) malloc(sizeof(HandValues));
    MadeHand->pair1 = 5;

    return Data_Wrap_Struct(self, NULL, NULL, &MadeHand);
}

void Init_ev() {
    rb_eval_string("require './lib/ev/pair_counter'");
    VALUE PairCounter = rb_path2class("EV::PairCounter");
    rb_define_method(PairCounter, "get_pairs_2", get_pairs_2, 0);
}

Ruby で get_pairs_2 を呼び出すと、次のエラーが発生します。

TypeError: wrong argument type EV::PairCounter (expected Class)

C が EV::PairCounter を文字列などではなく、スーパークラスとして表示していることを確認しました。

ちなみに、これは C 拡張 API が Data_Wrap_Struct について言っていることです。

C データを Ruby オブジェクトにカプセル化する

C ポインターを Ruby オブジェクト (いわゆる DATA) としてラップしてオブジェクト化するには、Data_Wrap_Struct() を使用します。

Data_Wrap_Struct(klass, mark, free, ptr)

Data_Wrap_Struct() は、作成された DATA オブジェクトを返します。klass 引数は、DATA オブジェクトのクラスです。mark 引数は、このデータが指す Ruby オブジェクトをマークする関数です。free 引数は、ポインタの割り当てを解放する関数です。これが -1 の場合、ポインターは単に解放されます。関数 mark と free は、ガベージ コレクターから呼び出されます。

4

1 に答える 1

1

問題は、 Data_Wrap_Struct(klass, mark, free, ptr) の klass が、データの送信先の klass ではなく、返される klass であるということでした。したがって、klass は C で定義および設定された Ruby クラスであり、この関数で Ruby に返されます。

于 2011-06-23T20:08:26.927 に答える