Passando valori di matrice rubino in una matrice C
-
12-10-2019 - |
Domanda
Sto cercando di fare un'estensione standalone FFT per Ruby in C, sulla base di questa ricetta
Ho notato diversi metodi per il passaggio di valori diversi tra Ruby e c. Tuttavia im abbastanza nuovo per entrambi rubino e C e non può capire come copiare una matrice da un oggetto di valore rubino in una matrice C.
L'errore di compilazione: SimpleFFT.c: 47: errore: subscripted valore non è né matrice né puntatore
E il codice:
#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;
}
Grazie in anticipo:)
Soluzione
inputArr
non può pedice perché è un VALUE
piuttosto che una matrice C. Vale a dire, si tratta di un tipo scalare. Per accedere a un particolare indice, l'uso
rb_ary_entry(inputArr, i)
Per inciso, si potrebbe desiderare di verificare in primo luogo che si tratta di un array:
Check_Type(rarray, T_ARRAY);
Altri suggerimenti
appare come rispondendo alla domanda (e il doppio controllo le mie fonti) mi ha aiutato a lavorare fuori la risposta.
sostituzione:
rb_ary_push(outputArr, DBL2NUM(X[i][0]));
con:
x[i][0]=NUM2DBL(rb_ary_pop(inputArr));
sembrava fare il trucco:)
Sono ancora si chiedono se questo è il modo più efficiente di fare le cose, ma funziona.