これは、私の問題を切り分けるコードです。
#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 は、ガベージ コレクターから呼び出されます。