用Rice调用C ++中的Ruby块

时间:2012-09-19 13:51:41

标签: c++ ruby

我正在为我正在编写的C ++库编写一个Ruby接口。 C ++库提供了几种基于比较函数的数据结构,例如FibonacciHeap。使用ruby比较函数可以正常工作,即以下Ruby代码可以工作:

f = FibonacciHeap.new
f.push(24)
f.push(2)
f.push(89)
raise unless f.top == 2

但我想让用户可以提供他自己的比较功能,例如像这样:

f = FibonacciHeap.new { |a, b| a.length <=> b.length }
f.push("asdf")
f.push("a")
f.push("adsfdsafdsaf")
raise unless f.top == "a"

但即使使用Google,我也没有找到如何在Rice中使用块。我发现的唯一一件事是如何从C ++迭代器中定义ruby每个方法,当然这需要一个块。我想一旦我存储了proc对象,就很容易了,我只是用适当的参数调用ruby方法“call”,但是如何检查构造函数是否被赋予一个块,如果是,则存储阻止进入proc对象?

如果我可以检查块占用的参数数量,那会更好,但我不知道这是否可行,但是用户可以在简单的情况下提供类似

的内容
f = FibonacciHeap.new { |a| a.length }

如果他不需要提供a <=> b功能的充分灵活性。

1 个答案:

答案 0 :(得分:2)

在C代码中,您可以调用:

rb_yield(value);

在Rice代码中,您可以使用:

Rice::protect(rb_yield, value);

(Rice :: protect确保正常的C ++异常行为)。

这就是Rice :: Module :: define_iterator如何屈服于ruby代码。