Ruby C扩展:将int函数转换为Ruby值

Ruby C扩展:将int函数转换为Ruby值,c,ruby,C,Ruby,我试图包装下面的函数以生成一个C扩展 int dsvd(float **a, int m, int n, float *w, float **v){ //do some things } 我有我的init,这不太正确: void Init_svd() { VALUE rb_mSvd = rb_define_module("Svd"); rb_define_method(rb_mSvd, "svd", dsvd, 0); } 我知道我需要包装dsvd,这样我就可以将值传

我试图包装下面的函数以生成一个C扩展

int dsvd(float **a, int m, int n, float *w, float **v){
    //do some things
}
我有我的init,这不太正确:

void Init_svd() {
    VALUE rb_mSvd = rb_define_module("Svd");
    rb_define_method(rb_mSvd, "svd", dsvd, 0);
}
我知道我需要包装dsvd,这样我就可以将
传递给
rb\u define\u方法
,但我不太清楚该怎么做。我试着修改答案,但还是弄不清楚。有什么建议吗


编辑*我还阅读了关于C扩展的实用程序员部分,但重点是对象创建/分配。我试图提供一个函数来执行一些转换并返回一个值,所以我无法在概念上进行匹配

如果整数适合Fixnum,则可以使用宏INT2FIX为dsvd()返回的整数返回Fixnum值。否则,您必须使用INT2NUM,它有函数调用开销(它调用rb_INT2NUM)。请在ruby.h中查找这些宏以了解更多详细信息

编辑:您的评论表明您需要更多帮助。你想要这样的东西。我还没有编译这个,它也没有检查参数的合理性,但它应该可以让你继续)。方法的签名看起来像是数组a和数组v中传递的值可能会被更改,并且此代码不会将任何更改复制回Ruby版本(使用rb_ary_store分配元素)

#包括
#包括
静态值rb_mSvd;
静态值
rb_svd(值自身、值a_数组、值m_v、值n_v、值w_v、值v_数组)
{
/*请注意,这里没有检查正确的类型或sane值*/
long a_len=RARRAY_len(a_数组);/*获取第一个(数组)参数的长度*/
float*a=(float*)malloc(sizeof(float)*a_len);/*为副本留出空间*/
int m=NUM2INT(m_v);
int n=NUM2INT(n_v);
浮点数w=NUM2DBL(w_v);
长v_len=RARRAY_len(v_数组);
浮动*v=(浮动*)malloc(浮动大小)*v_len);
int结果;
对于(int i=0;i
那么我会做类似于
值rb\u svd(值self,值**a,值m,值n,值*w,值**v){}
的事情吗?还是我应该打开args?太棒了!谢谢,看来这会奏效的。
    #include        <ruby.h>
    #include        <ruby/intern.h>

    static VALUE rb_mSvd;

    static VALUE
    rb_svd(VALUE self, VALUE a_array, VALUE m_v, VALUE n_v, VALUE w_v, VALUE v_array)
    {
            /* Note that there is no checking here for correct types or sane values! */
            long    a_len = RARRAY_LEN(a_array);                    /* get the length of first (array) argument */
            float*  a = (float*)malloc(sizeof(float)*a_len);        /* make space for the copies */
            int     m = NUM2INT(m_v);
            int     n = NUM2INT(n_v);
            float   w = NUM2DBL(w_v);
            long    v_len = RARRAY_LEN(v_array);
            float*  v = (float*)malloc(sizeof(float)*v_len);
            int     result;

            for (int i = 0; i < a_len; i++)
                    a[i] = NUM2DBL(rb_ary_entry(a_array, i));

            for (int i = 0; i < v_len; i++)
                    v[i] = NUM2DBL(rb_ary_entry(v_array, i));

            result = dsvd(&a, m, n, w, &v);

            free(a);
            free(v);
            return INT2NUM(result);
    }               

    void Init_svd()
    {
            rb_mSvd = rb_define_module("Svd");
            rb_define_method(rb_mSvd, "svd", rb_svd, 5);
    }