Rcpp:在 R 中调用 c++ 函数而不导出 c++ 函数
Rcpp: calling c++ function in R without exporting c++ function
我正在尝试用Rcpp制作一个包。我将所有C++
函数都放在一个.cpp
文件中,如下所示:
double meanvec(NumericVector x) {
int n = x.size();
double tot = 0;
for (int i = 0; i < n; i++) {
tot += x[i];
}
tot /= n;
return tot;
}
double inprod(NumericVector u, NumericVector v) {
int m = u.size();
double val = 0;
for (int i = 0; i < m; i++) {
val += u[i] * v[i];
}
return val;
}
NumericVector lincoef(NumericVector x, NumericVector y) {
int n = x.size();
double xm = meanvec(x);
double ym = meanvec(y);
NumericVector xa(n);
for (int i = 0; i < n; i++) {
xa[i] = x[i] - xm;
}
NumericVector ya(n);
for (int i = 0; i < n; i++) {
ya[i] = y[i] - ym;
}
double b1 = inprod(xa, ya) / inprod(xa, xa);
double b0 = ym - (b1 * xm);
NumericVector beta = NumericVector::create(b0, b1);
return beta;
}
基本上,最后一个函数将两个向量作为输入并输出单个向量。我想将此函数调用到一个单独的.R
文件中,我正在尝试在其中编写另一个函数。像这样:
#' Title
#'
#' @param x Numeric vector.
#' @param y Numeric vector.
#'
#' @return
#' @export
linfit338 = function(x, y){
beta = .Call(`_pkg338_lincoef`, x, y)
fmod = function(x){
beta[1] + beta[2]*x
}
flist = list(beta, fmod)
return(flist)
}
这里的输出是一个列表,其中第一个元素是来自正在调用的C++
函数的向量,第二个元素是创建的函数。当我尝试安装并重新启动时,我收到以下错误消息:
RcppExports.o:RcppExports.cpp:(.rdata+0x790): undefined reference to `_pkg338_lincoef'
我的猜测是这与导出函数有关。当我在C++
文件中的lincoef
函数上方添加// [[Rcpp::export]]
时,我没有收到任何错误消息,并且我的最终R
函数可以正常工作。但是,我的整个目标是我根本不希望导出lincoef
函数。
有什么方法可以解决这个问题吗?我也愿意接受有关如何改进这些文件的组织的建议,因为这是我第一次使用Rcpp
构建软件包。
我认为您可能混淆了导出C++代码以在 R 中使用的概念(通过// [[Rcpp::export]]
(,这与从包中导出 R 函数完全不同,即将这些功能提供给包的最终用户。
要使 Rcpp 函数完全可以从 R 中调用,您需要// [[Rcpp::export]]
它们。如果不执行此操作,则 R 包中将不提供任何C++代码。
听起来您想做的是在软件包中使用 Rcpp 导出的函数,但对最终用户隐藏它们。这是 Rcpp 的一个常见用例,因为它允许您拥有一个充当C++代码的最终用户接口的 R 函数,同时让您在未来的开发中自由更改C++实现,而不会有破坏现有用户代码的风险。
在包中创建的任何函数(无论是 R 函数还是 Rcpp 导出的函数(都必须主动从包中导出,以便最终用户可以使用。这与// [[Rcpp::export]]
不同,后者需要从包的 R 代码中访问C++函数。
只有在项目根目录的NAMESPACE
文件中指定任何 R 函数时,才会从 R 包中导出这些函数。因此,要导出myfunction()
您需要在命名空间文件中有一行表示export(myfunction)
。您正在使用 roxygen2,只要您在 roxygen 框架中写入@export
,它就会自动生成此行。使用 roxygen 导出系统的另一种方法是在NAMESPACE
文件中指定一个exportPattern
,该使用正则表达式仅导出名称与特定模式匹配的函数。
我通常的工作流程是通过编写我的C++函数来为任何 Rcpp 导出的函数添加句点,如下所示:
// [[Rcpp::export(.MyCppFunction)]]
int BoringFunction() { return 0; }
我现在可以从 R 调用 C++ 函数,如下所示:
MyRFunction <- function()
{
result <- .MyCppFunction()
return(result)
}
我的NAMESPACE
文件的第一行如下所示:
exportPattern("^[[:alpha:]]+")
这意味着我的包中任何以字母开头的 R 函数都将被导出。由于我Rcpp::export
的所有函数都以句点开头,因此我可以在 R 包内部使用它们,但它们不会导出给最终用户。
换句话说,包的最终用户可以调用MyRFunction()
但如果他们尝试调用.MyCppFunction
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗