我正在尝试重新实现这个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 矩阵库的 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 中是可以做的,首先你需要包含标头<stdarg.h>
然后将函数设置为如下所示
type function(type argument , ...){}
之后使用变量类型va_list
和三个函数va_start
,va_end
和va_arg
来"导航"参数,如下所示