我有一堆Rcpp代码,我必须重写为一个没有Rcpp的C/C++扩展(由于它的许可),幸运的是它没有我担心的那么痛苦。但是为了编写最干净的代码,我想确保我没有过度使用PROTECT/UNPROTECT。写R扩展医生提到,“保护眼前的一切并不是个好主意.”所以我想尽职尽责。
这是我想要检查的东西。在阅读为R编写C扩展的所有示例时,我看到了许多示例,其中作者保护传递函数的参数,如取自这篇文章的这些例子。
#include <R.h>
#include <Rdefines.h>
#include <string.h>
SEXP helloC1(SEXP greeting) {
int i, vectorLength, stringLength;
SEXP result;
PROTECT(greeting = AS_CHARACTER(greeting));
vectorLength = LENGTH(greeting);
PROTECT(result = NEW_INTEGER(vectorLength));
for (i=0; i<vectorLength; i++) {
stringLength = strlen(CHAR(STRING_ELT(greeting, i)));
INTEGER(result)[i] = stringLength;
}
UNPROTECT(2);
return(result);
}SEXP问候语作为一个参数被传递进来,作者立即保护它。然而,在写R扩展中,我注意到了这一点:
对于R已经知道正在使用的对象,不需要保护。特别是,这适用于函数参数。
因此,为了进行理智检查,有人能告诉我,这些代码示例中的作者保护传入的参数是否可以被删减?如果是这样的话,我将能够使我的代码更加简洁。
发布于 2016-10-01 03:05:21
输入参数不需要被保护,但是你误解了一点--被保护的不是输入参数greeting,而是由AS_CHARACTER(greeting)生成的新SEXP。
这有点让人困惑,因为greeting变量立即被重新分配,但实际上,您现在有了指向一个全新SEXP的greeting,并且需要保护这个新对象不受垃圾收集器的影响。
发布于 2016-09-30 13:42:27
我有一堆Rcpp代码,我必须重写为一个没有Rcpp的C/C++扩展(因为它的许可证)。
你可能需要一个(更好的)律师。R本身处于与Rcpp相同的许可下,因此“避免”Rcpp对您几乎没有好处,因为链接聚合仍然是GPL 2或更高版本。
编辑:这里有两个更简单和更短的函数实现。你可能会发现它们更容易阅读和使用。在用户空间中没有PROTECT舞蹈,因为Rcpp会处理这一切。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector helloC2(CharacterVector v) {
IntegerVector res(v.size());
for (int i=0; i<v.size(); i++) {
res[i] = strlen(v[i]);
}
return(res);
}
// [[Rcpp::export]]
IntegerVector helloC3(CharacterVector v) {
return wrap(sapply(v, strlen));
}它们产生(当然)相同的功能输出。
首先,你的:
R> system("cd /tmp && R CMD SHLIB prot.c")
R> dyn.load("/tmp/prot.so")
R> .Call("helloC1", c("the", "quick", "brown", "fox"))
[1] 3 5 5 3
R> 其次,我的:
R> Rcpp::sourceCpp("/tmp/prot.cpp")
R> helloC2(c("the", "quick", "brown", "fox"))
[1] 3 5 5 3
R> helloC3(c("the", "quick", "brown", "fox"))
[1] 3 5 5 3
R> https://stackoverflow.com/questions/39791553
复制相似问题