首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我们使用rb_protect时,是否强制使用rb_funcall

当我们使用rb_protect时,是否强制使用rb_funcall
EN

Stack Overflow用户
提问于 2016-04-02 09:32:46
回答 1查看 154关注 0票数 1

我已经开始为clang库编写一个ruby模块。

我在clang c模块中封装了以下内容

代码语言:javascript
复制
unsigned clang_visitChildren(CXCursor parent,
                             CXCursorVisitor visitor,
                             CXClientData client_data);

像这样的来访者:

代码语言:javascript
复制
typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor,
                                                   CXCursor parent,
                                                   CXClientData client_data);

红宝石代码(正在工作)如下所示:

代码语言:javascript
复制
Clangc.visit_children(cursor: tu.cursor) do |cursor, parent| 
  puts cursor
  puts parent
  Clangc::ChildVisitResult::RECURSE  
end

其思想是将块作为参数传递给访问者,并在访问者中调用它。

C胶代码如下所示:

代码语言:javascript
复制
VALUE
m_clangc_visit_children_with_proc(VALUE self, VALUE cursor, VALUE aproc)
{
    if (rb_class_of(aproc) != rb_cProc) rb_raise(rb_eTypeError, "Need a block");

    VALUE callback = aproc;
    Cursor_t *c;
    unsigned ret_with_break;

    Data_Get_Struct(cursor, Cursor_t, c);
    ret_with_break = clang_visitChildren(c->data,
                                         visitor,
                                         (CXClientData) callback);
    /*return false if ret_with_break == 0*/
    return NOT_0_2_RVAL(ret_with_break);
}

与访问者(回调):

代码语言:javascript
复制
static enum CXChildVisitResult
visitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
    /*basic variables initialization...*/
    r_ret = rb_funcall(callback, rb_intern("call"), 2, r_cursor, r_parent);

    if (TYPE(r_ret) == T_FIXNUM)
    {
        ret = NUM2UINT(r_ret);
        if (ret == CXChildVisit_Break || ret == CXChildVisit_Continue ||
            ret == CXChildVisit_Recurse)
            return ret;
        else
            return CXChildVisit_Break;
    }
    else
        return CXChildVisit_Break;
}

我的答案是我应该在这里使用rb_protect吗?

代码可以在这里找到:

functions.c#L146

https://github.com/cedlemo/ruby-clangc/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-06 09:24:29

经过一些测试,在阅读了其他人的代码之后,我得出的结论是,使用rb_protect封装rb_funcall并不是强制性的。

当您需要在C中处理由rb_funcall执行的ruby块或procs中可能的异常时,应该使用它。

我应该提到,在C中嵌入ruby解释器时,处理这些异常必须比编写一些C ruby扩展时更重要。

参考资料:

  • git clone git://libvirt.org/ruby-libvirt.git
  • git clone https://github.com/ruby-gnome2/ruby-gnome2.git
  • http://clalance.blogspot.fr/2011/01/writing-ruby-extensions-in-c-part-5.html
  • https://silverhammermba.github.io/emberb/c/
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36371546

复制
相关文章

相似问题

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