2012-06-22 100 views
0
arr=Array.new(3) 
arr[0]=5 
arr[1]=3 
arr[2]=2 

这些行应该调用根据该该功能,https://github.com/ruby/ruby/blob/trunk/array.c#L568http://www.ruby-doc.org/core-1.9.3/Array.html我如何访问C中的红宝石数组的值? (编辑array.c:从红宝石源代码rb_ary_initialize)

因此,我已加入几行有显示数组的值的。但是我没有得到预期的结果。

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); 
    } 
} 

我得到的结果是这样的:

arr=Array.new(3) 
arr[0]=5 
arr[1]=3 
arr[2]=2 
r: 9 
r: 9 
r: 9 

为什么是这样的结果?为什么是9?

我按照这些来解决这个问题:

谁能请帮助显示红宝石阵/ printf的价值在C?

回答

0

这没有任何意义:

result = LONG2NUM(s_arr[i]); 

LONG2NUM用于一个C long int转换成一个Ruby VALUE,装有一; s_arr[i]已经是VALUE,所以你实际上是在做像VALUE v = LONG2NUM((VALUE)5)这样的事情。 LONG2NUMruby.h定义为包装此:

#define LONG2NUM_internal(v) (FIXABLE(v) ? LONG2FIX(v) : rb_int2big(v)) 

如果v镶嵌在VALUE,而不将其转换为BIGNUM,那么你最终会使用这样的:

#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG)) 

所以你基本上在一个指针上做了一堆小小的争论,并想知道为什么它总是说9;认为自己幸运(或不幸),它不会说分段错误

要将包含数字的VALUE转换为C整数。你可能想使用FIX2LONG

#define FIX2LONG(x) (long)RSHIFT((SIGNED_VALUE)(x),1) 

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 

因此,像这样:

long result; 
for(i = 0; i < len; i++) { 
    result = NUM2LONG(s_arr[i]); 
    printf("r: %ld\n", result); 
} 

注意,因为我们使用的是long小号现在改用%ld和我们总是打开所有抱怨不匹配的编译器标志printf格式和参数秒。当然,这假定您确定该数组包含的数字将适合C long

+0

使用NUM2LONG,我得到这个,'t.rb:3:在初始化':从t.rb在新 \t:从零的隐式转换为整数(类型错误)从t.rb \t:3 3 :

' – shibly

+0

@prime:我不知道't.rb'的第三行是什么。 –

+0

@prime:这个错误可能来自'numeric.c'中的'rb_num2long',并且意味着您试图在Ruby'nil'值上使用'NUM2LONG'。你确定你没有跑出阵列末端或类似的东西吗? –