Передача значений ruby-массива в массив C - PullRequest
4 голосов
/ 24 декабря 2010

Я пытаюсь сделать автономное расширение FFT для рубина в C на основе этого рецепта

Я отметил несколько способов передачи различных значений между ruby ​​и c. Однако я довольно плохо знаком с ruby ​​и C и не могу понять, как скопировать массив из объекта VALUE ruby ​​в массив C.

Ошибка компиляции: SimpleFFT.c: 47: ошибка: подписанное значение не является ни массивом, ни указателем

И код:

#include "ruby.h"
#include "fft.c" // the c file I wish to wrap in ruby

VALUE SimpleFFT = Qnil;
void Init_simplefft();
VALUE method_rfft(VALUE self, VALUE anObject);

void Init_simplefft() {
    SimpleFFT = rb_define_module("SimpleFFT");
    rb_define_method(SimpleFFT, "rfft", method_rfft, 1);
}

VALUE method_rfft(VALUE self, VALUE inputArr) {
    int N = RARRAY_LEN(inputArr); // this works :)

    // the FFT function takes an array of real and imaginary paired values
    double (*x)[2] = malloc(2 * N * sizeof(double)); 
    // and requires as an argument another such array (empty) for the transformed output
    double (*X)[2] = malloc(2 * N * sizeof(double));

    for(i=0; i<N; i++) {
        x[i][0]=NUM2DBL(inputArr[i]); // ***THIS LINE CAUSES THE ERROR***
        x[i][1]=0;  // setting all the imaginary values to zero for simplicity
    }

    fft(N, x, X); // the target function call

    // this bit should work in principle, dunno if it's optimal
    VALUE outputArr = rb_ary_new();
    for(i=0; i<N; i++){
        rb_ary_push(outputArr, DBL2NUM(X[i][0]));
    }

    free(x);
    free(X);

    return outputArr;
}

Заранее спасибо:)

Ответы [ 2 ]

4 голосов
/ 24 декабря 2010

Вы не можете подписать inputArr, потому что это VALUE, а не массив C.Т.е. это скалярный тип.Чтобы получить доступ к определенному индексу, используйте

rb_ary_entry(inputArr, i)

В качестве отступления, вы можете сначала проверить, что это массив:

Check_Type(rarray, T_ARRAY);
2 голосов
/ 24 декабря 2010

похоже на то, что ответ на вопрос (и двойная проверка моих источников) помогли мне выработать ответ.

заменив:

    rb_ary_push(outputArr, DBL2NUM(X[i][0]));

на:

    x[i][0]=NUM2DBL(rb_ary_pop(inputArr));

казалось, добился цели:)

Мне все еще интересно, является ли это наиболее эффективным способом ведения дел, но он работает.

...