【问题标题】:Passing ruby array values into a C array将 ruby​​ 数组值传递给 C 数组
【发布时间】:2010-12-24 00:59:14
【问题描述】:

我正在尝试基于 this recipe 为 C 中的 ruby​​ 制作独立的 FFT 扩展

我已经注意到在 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;
}

提前致谢:)

【问题讨论】:

    标签: c ruby ruby-c-extension


    【解决方案1】:

    您不能为inputArr 下标,因为它是VALUE 而不是C 数组。即,它是一个标量类型。要访问特定索引,请使用

    rb_ary_entry(inputArr, i)
    

    顺便说一句,您可能想先验证它是一个数组:

    Check_Type(rarray, T_ARRAY);
    

    【讨论】:

    • 感谢您的提示 :)。我回答自己没有刷新,哎呀!是否有任何理由访问数组条目可能比弹出值更好或更差?
    • @Nat 我不知道 Ruby 如何实现其推送/弹出机制与随机访问。如果一种方案涉及改组内容或重新分配内存,那么效率会降低。可悲的是,如果不深入研究 Ruby 源代码,我不确定它是什么……但是,如果您真的关心性能,您可以分析您的应用程序。
    【解决方案2】:

    看起来回答问题(并仔细检查了我的来源)帮助我找到了答案。

    替换:

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

    与:

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

    似乎成功了:)

    我仍然想知道这是否是最有效的做事方式,但它确实有效。

    【讨论】:

      猜你喜欢
      • 2016-08-01
      • 2016-11-23
      • 1970-01-01
      • 2018-09-26
      • 2020-09-03
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      相关资源
      最近更新 更多