Это мой урезанный код, который изолирует мою проблему:
#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);
}
Когда я вызываю get_pairs_2 в ruby, я получаю эту ошибку:
TypeError: wrong argument type EV::PairCounter (expected Class)
Я подтвердил, что Cпросматривает EV :: PairCounter как суперкласс, а не как строку или что-то в этом роде.
Кстати, это то, что API расширения C говорит о Data_Wrap_Struct:
Инкапсуляция данных C в Rubyobject
Чтобы обернуть и объективировать указатель C как объект Ruby (так называемый DATA), используйте Data_Wrap_Struct ().
Data_Wrap_Struct(klass, mark, free, ptr)
Data_Wrap_Struct () возвращает созданный объект DATA.Аргумент klass является классом для объекта DATA.Аргумент mark - это функция для маркировки объектов Ruby, на которые указывают эти данные.Свободный аргумент - это функция для освобождения выделения указателя.Если это -1, указатель будет просто освобожден.Функции mark и free будут вызываться из сборщика мусора.