首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我使用rb_funcall调用Hash#has_key时,为什么会出现段错误?

当我使用rb_funcall调用Hash#has_key时,为什么会出现段错误?
EN

Stack Overflow用户
提问于 2012-08-24 03:27:22
回答 1查看 541关注 0票数 1

我不确定我做错了什么。我有一个Ruby散列,我将其作为此函数的第三个参数Test::test()传入。

代码语言:javascript
复制
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);
}

我听说如果你试图调用某个对象上不存在的函数,你会得到一个段错误。我还检查了对象是否响应has_key?

代码语言:javascript
复制
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线路上。

代码语言:javascript
复制
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

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-24 04:29:07

我想通了。看起来rb_intern("whatever!")返回一个ID,而rb_funcall需要一个VALUE。因此,对rb_funcall的调用应该如下所示:

代码语言:javascript
复制
rb_funcall(options, rb_intern("has_key?"), 1, ID2SYM(rb_intern("dtype")));

这很令人困惑,因为:has_key?是一个ID,而且工作得很好--但是参数本身需要是VALUE类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12098683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档