[英]How can i access the value of a ruby array in C? (editing array.c:rb_ary_initialize from ruby source code)
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
These lines should call this function, https://github.com/ruby/ruby/blob/trunk/array.c#L568 according to this, http://www.ruby-doc.org/core-1.9.3/Array.html 这些行应根据http://www.ruby-doc.org/core-1.9.3/来调用此函数https://github.com/ruby/ruby/blob/trunk/array.c#L568 Array.html
So I have added couple of lines there to display the values of array. 因此,我在其中添加了几行以显示数组的值。 But i didn't get the expected result.
但是我没有得到预期的结果。
else {
memfill(RARRAY_PTR(ary), len, val);
ARY_SET_LEN(ary, len);
int i;
int result;
result = 0;
VALUE *s_arr = RARRAY_PTR(ary);
for(i = 0; i < len; i++) {
result = LONG2NUM(s_arr[i]);
printf("r: %d\n",result);
}
}
I got the result like this: 我得到这样的结果:
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
r: 9
r: 9
r: 9
Why is this result? 为什么会这样呢? Why 9?
为什么是9?
I have followed these to solve it: 我已经遵循这些来解决它:
Can anyone please help to display/printf the value of Ruby array in C? 谁能帮助显示/打印C语言中Ruby数组的值?
This doesn't make any sense: 这没有任何意义:
result = LONG2NUM(s_arr[i]);
LONG2NUM
is used to convert a C long int
to a Ruby VALUE
that holds a number; LONG2NUM
用于将C long int
转换为包含数字的Ruby VALUE
; s_arr[i]
is already a VALUE
so you're effectively doing things like VALUE v = LONG2NUM((VALUE)5)
. s_arr[i]
已经是一个VALUE
因此您实际上正在执行VALUE v = LONG2NUM((VALUE)5)
类的事情。 LONG2NUM
is defined in ruby.h
as a wrapper for this: 在
ruby.h
LONG2NUM
定义为此:
#define LONG2NUM_internal(v) (FIXABLE(v) ? LONG2FIX(v) : rb_int2big(v))
and if v
fits in a VALUE
without converting it to a bignum, then you end up using this: 如果
v
符合VALUE
而不将其转换为大数,那么您最终将使用以下代码:
#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
So you're basically doing a bunch of bit wrangling on a pointer and wondering why it always says 9
; 所以您基本上是在指针上进行一堆争吵,想知道为什么它总是说
9
; consider yourself lucky (or unlucky) that it doesn't say segmentation fault . 认为自己很幸运(或不幸运)并没有表示细分错误 。
You want to convert a VALUE
which holds a number to a C integer. 您想要将包含数字的
VALUE
转换为C整数。 You probably want to use FIX2LONG
: 您可能要使用
FIX2LONG
:
#define FIX2LONG(x) (long)RSHIFT((SIGNED_VALUE)(x),1)
or NUM2LONG
: 或
NUM2LONG
:
#define NUM2LONG_internal(x) ((long)(FIXNUM_P(x) ? FIX2LONG(x) : rb_num2long(x)))
#ifdef __GNUC__
#define NUM2LONG(x) \
__extension__ ({VALUE num2long_x = (x); NUM2LONG_internal(num2long_x);})
#else
static inline long
NUM2LONG(VALUE x)
{
return NUM2LONG_internal(x);
}
#endif
So something like this: 所以像这样:
long result;
for(i = 0; i < len; i++) {
result = NUM2LONG(s_arr[i]);
printf("r: %ld\n", result);
}
Note the switch to %ld
since we're using long
s now and we always turn on all the picky compiler flags that complain about mismatched printf
formats and arguments. 注意,因为我们现在使用
long
s,所以切换到%ld
并且我们总是打开所有挑剔的编译器标志,这些标志抱怨printf
格式和参数不匹配。 Of course, this assumes that you are certain that the array contains numbers that will fit in a C long
. 当然,这假定您确定数组包含适合C
long
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.