在 C 中构造参数以使用可变数量的参数调用 Ruby C 扩展

标签 c ruby

我正在尝试重新实现这个 Ruby 方法:

  def reshape new_shape
    t = reshape_clone_structure(new_shape)
    left_params  = [:*]*new_shape.size
    right_params = [:*]*self.shape.size
    t[*left_params] = self[*right_params]
    t
  end

作为 Ruby matrix library 的 C 扩展.

我被困在如何将多个值传递给 []= 上,它是在具有以下定义的现有 C 扩展中实现的:

static VALUE nm_mset(int argc, VALUE* argv, VALUE self)

如何将 Ruby 代码 t[*left_params] = 转换为 C?

最佳答案

nm_mset 方法使用 Ruby C 扩展的标准约定。 argc 变量是一个整数,指定发送的参数数量。那么argv是一个VALUE *类型的C数组/指针,它必须包含所有Ruby-ish参数(对于赋值,这些参数中的最后一个是右侧的值)。第三,self 是 Ruby 对象接收器 - 但请记住,这可能是类或它的实例,具体取决于为 Ruby 定义方法的方式。

要调用它,您需要构造一个 VALUE * 数组,其中每个参数都是一个 VALUE,并按正确的顺序发送。

我认为你想做这样的事情:

// Assuming you have following values already processed
// Assignments are not shown here - that is work for you!
VALUE self; 
VALUE t; 
int self_size; 
int new_size; 

//////////////////////////////////////////////////////////////////
//
// Assuming you set above values correctly, the following should
// work.

int i;

// Get reference to :*
VALUE asterisk = ID2SYM( rb_intern("*") );

// NB +1, we need to add call to self[ *right_params ] to end later
VALUE *left_params = ALLOC_N( VALUE, new_size + 1 );
for(i=0;i<new_size;i++) { left_params[i] = asterisk; }

VALUE *right_params = ALLOC_N( VALUE, self_size );
for(i=0;i<self_size;i++) { right_params[i] = asterisk; }

// equivalent to self[ *right_params ], 
// but we push it straight into end of left_params ready for next step
left_params[ new_size ] = nm_mget( self_size, right_params, self );

// equivalent to t[ *left_params ] =
// Note +1 to size again, the last item is the value to assign
nm_mset( new_size + 1, left_params, t );

// Tidy up
xfree( left_params );
xfree( right_params );

return t;

关于在 C 中构造参数以使用可变数量的参数调用 Ruby C 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21861654/

相关文章:

c - fork() 在这个 C 程序中是如何工作的?

ruby-on-rails - 如何按关联表的计算进行过滤?

ruby-on-rails - ActiveRecord::Relation 问题检查为零? -- rails 3.1

ruby - 为什么 truth && "string"返回 "string"

javascript - Rails 中的嵌入式 Google map 没有响应

java - 在 Ruby 中创建类似字节缓冲区的对象

c - 为什么“while(!feof(file))”总是错误的?

c - 在C源代码中加密密码

c - 显示星号与使用函数显示字符

编译从书中逐字复制的代码会导致编译器错误