Что я должен вернуть как класс в Data_Wrap_Struct? - PullRequest
2 голосов
/ 23 июня 2011

Это мой урезанный код, который изолирует мою проблему:

#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 будут вызываться из сборщика мусора.

1 Ответ

1 голос
/ 24 июня 2011

Проблема заключалась в том, что klass в Data_Wrap_Struct (klass, mark, free, ptr) - это класс, который вы возвращаете, а не класс, в который вы отправляете данные. Таким образом, klass является классом ruby, определенным и заполненным в C, а затем возвращенным в ruby ​​с помощью этой функции.

...