我想从我的C API代码中调用一个ruby中的全局方法。在Ruby中:
def giveMeABlock(*args)
puts "Starting giveMeABlock with #{args.inspect}"
yield if block_given?
end
正如我后来了解到的那样,全局函数实际上只是Object中的私有函数,所以我们可以从任何地方调用它们。
在C中,我想调用这个方法,我可以使用rb_funcallv:
VALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv)
Invokes a method, passing arguments as an array of values. Able to call even private/protected methods.
对于这个具体的例子,我可以这样做:
rb_funcallv(self, rb_intern("giveMeABlock"), 0, NULL);
我们能够调用该方法,尽管没有提供任何块。
要调用块,我们有:
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE passed_procval)
Same as rb_funcallv_public, except passed_procval specifies the block to pass to the method.
但是,像rb_funcallv_public一样,它只能调用公共方法。这意味着如果我尝试:
rb_funcall_with_block(self, rb_intern("giveMeABlock"), 0, NULL, block);
我得到:
private method `giveMeABlock' called for main:Object (NoMethodError)
那么,为什么没有可以提供块的私有方法的funcall,或者我错过了什么?如何完成这个看似简单的任务?
我已经意识到我可以在Object类中定义方法,然后它就可以工作了(因为现在它是公共的),但这似乎很奇怪,并且假设我有能力改变Ruby源代码。
1条答案
按热度按时间tyg4sfes1#
我迟到了,你可能不再需要这个答案了,但我会为后代发布:
我找到的解决方法是只做函数
public
。您可以直接从Ruby代码中执行此操作:或者如果这不是一个选择(例如,如果你不能改变你需要运行的Ruby代码),你可以从C代码中公开它:
现在它是公共的,您可以使用
rb_funcall_with_block
调用它。