Как получить доступ к массиву ruby ​​из моего расширения c? - PullRequest
2 голосов
/ 23 июня 2011

Я получаю эту ошибку

ev.c:11: error: subscripted value is neither array nor pointer

для этой строки

printf("%d\n", pairs[0][0]);

В этом коде

static VALUE EV;
static VALUE PairCounter;

static VALUE 
sort_pairs_2(VALUE self) {
    VALUE pairs;

    pairs = rb_ivar_get(self, rb_intern("pairs"));
    printf("%d\n", pairs[0][0]);
  return Qnil;
}

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

Я неправильно использую self, а rb_ivar_get на самом деле не указывает на класс PairCounter?

Ответы [ 2 ]

3 голосов
/ 23 июня 2011

Я почти уверен, что вам нужно использовать макрос RARRAY_PTR для pairs, чтобы получить базовый массив;например, внутренняя реализация Array # push (для 1.9.2) выглядит следующим образом:

static VALUE
rb_ary_push_1(VALUE ary, VALUE item)
{
    long idx = RARRAY_LEN(ary);

    if (idx >= ARY_CAPA(ary)) {
        ary_double_capa(ary, idx); 
    }
    RARRAY_PTR(ary)[idx] = item;
    ARY_SET_LEN(ary, idx + 1);   
    return ary;
}

if просто сортирует любое необходимое изменение размера, тогда есть RARRAY_PTR(ary)[idx] для доступа к одному слотув массиве.

У меня нет официальных ссылок, подтверждающих это, но, надеюсь, это будет полезно.

1 голос
/ 08 марта 2012

Доступ к массивам Ruby осуществляется с помощью функций rb_ - не так, как у обычных массивов C.

Использование rb_ary_entry

VALUE rb_ary_entry(VALUE self, long index")

Возвращает элемент массива self в index.

Справка:

http://ruby -doc.org / документы / ProgrammingRuby / html / ext_ruby.html

См. Список общих функций Array в разделе «Часто используемые методы» .

...