在将对象传递给 C++ 时,R 的垃圾收集存在一些问题。
我们有以下场景:
- 我们在 R 中创建一个匿名函数,并将其传递给 C++ 代码(通过
.Call()
) - C++ 代码存储 R 函数对象以供以后使用(作为
SEXP
类型)并返回 - 稍后,其他一些 C++ 代码使用
R_tryEval()
在第 2 步和第 3 步之间,R 函数对象似乎被 R 垃圾收集。这会导致崩溃,因为R_tryEval()
尝试执行不再代表有效 R 函数对象的东西。这很公平,因为我们没有做任何事情来告诉 R 函数对象仍在使用中......
考虑到这一点:
- 有没有办法从 C++ 代码中将 R 函数对象标记为正在使用(这样它就不会被 gc'd )?
- 还是有一种安全的方法可以在 C++ 代码中复制 R 函数对象,并在我们调用后手动处理它
R_tryEval()
?
(据我所知,PROTECT()
/UNPROTECT()
宏在这里不是一个选项,因为它们应该在同一范围内平衡。如,我们不能PROTECT()
在函数第一次传递给 C++ 时调用,然后UNPROTECT()
在它之后调用被处决。)