2012-08-23 64 views
1

我不知道我在做什麼錯。我收到了一個Ruby散列,作爲此函數的第三個參數Test::test()當我使用rb_funcall調用Hash#has_key時,爲什麼會出現段錯誤?

static VALUE nm_test(VALUE self, VALUE str, VALUE from, VALUE options) { 
    if (TYPE(options) != T_HASH) { 
    // raises error 
    } 

    if (rb_funcall(options, rb_intern("has_key?"), 1, rb_intern("dtype")) == Qtrue) { // SEGFAULT 
    // success 
    } 

    // other stuff 
} 

void Init_test() { 
    cTest = rb_define_module("Test"); 

    rb_define_singleton_method(cTest, "test", nm_test, 3); 
} 

我聽說,如果你試圖調用不某些對象上存在的函數,你會得到一個segfault。我還檢查了對象是否響應has_key?

if (TYPE(options) != T_HASH) { 
    rb_raise(rb_eArgError, "third argument to repack must be hash"); 
} else if (!rb_respond_to(options, rb_intern("has_key?"))) { 
    rb_raise(rb_eArgError, "hash does not respond to has_key?!"); 
} 

這不會觸發錯誤。所以它絕對是一個哈希,並且肯定有Hash#has_key?

下面是實際代碼(不是上面的代碼)的實際回溯。段錯誤位於rb_funcall行。

Program received signal SIGSEGV, Segmentation fault. 
rb_type (obj=44840) at ./include/ruby/ruby.h:1344 
1344 ./include/ruby/ruby.h: No such file or directory. 
(gdb) bt 
#0 rb_type (obj=44840) at ./include/ruby/ruby.h:1344 
#1 rb_any_hash (a=44840) at hash.c:83 
#2 0x080fc570 in st_lookup (table=0x8fa0470, key=44840, value=0x0) at st.c:341 
#3 0x08066ef8 in rb_hash_has_key (hash=144171660, key=44840) at hash.c:1516 
#4 0x08157f7d in vm_call0 (th=0x8265b88, recv=144171660, id=5127, argc=1, argv=0xbfffdf60, me=0x82ce480) 
    at vm_eval.c:79 
#5 0x081587c4 in rb_call (scope=CALL_FCALL, argv=0xbfffdf60, argc=1, mid=5127, recv=144171660) at vm_eval.c:456 
#6 rb_funcall (recv=144171660, mid=5127, n=1) at vm_eval.c:658 
#7 0xb70933f8 in nm_rbstring_matlab_repack (self=142142600, str=144171680, from=12992526, options=144171660) 
    at ../../../../ext/nmatrix/util/io.cpp:210 

任何想法?

+0

謝謝,對不起。以下是實際代碼的一部分:https://gist.github.com/3440958 - 希望讓人們閱讀起來更簡單。 –

+0

哦,段錯誤在要點的第31行。 –

回答

1

想通了。看起來rb_intern("whatever!")返回ID,並且rb_funcall需要VALUE。所以調用rb_funcall應該是這樣的:

rb_funcall(options, rb_intern("has_key?"), 1, ID2SYM(rb_intern("dtype"))); 

這是令人困惑,因爲:has_key?得到是一個ID,並且工作得很好 - 但參數本身必須VALUE型。

相關問題