如何使用Rcpp使执行就地操作的C ++函数可用于另一个R包?

问题描述

说我有一个名为“ packA”的R软件包,其中包含以下文件“ funcA.cpp”:

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcA (arma::vec& x) {
  x += 1;
}

从R调用此函数会产生预期结果,即就地向向量的每个元素加1:

> vec <- c(1,2,3)
> funcA(vec)
> vec
[1] 2 3 4

现在说我有第二个软件包“ packB”,它想调用函数“ funcA”。它包含以下名为“ funcB.cpp”的文件:

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcB() {
  arma::vec x = {1,3};

  Rcout << x << "\n";
  packA::funcA(x);
  Rcout << x << "\n";
}

调用此函数不再产生所需的结果,因为似乎向量x不再就地修改:

> funcB()
   1.0000
   2.0000
   3.0000

   1.0000
   2.0000
   3.0000

在仍然使用Rcpp的同时,有什么方法可以保留C ++函数的就地操作吗?预先感谢您的任何建议。

编辑: 我根据DirkEddelbüttel的建议修改了“ funcB.cpp”:

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcB(arma::vec& y) {
  packA::funcA(y);
}

不幸的是,从R调用函数时的结果是相同的:

> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 3 

修改2: 经过一些进一步的实验,我注意到,arma::vec& x一旦进入funcA的足迹,一切就开始崩溃。只需使用NumericVector即可:

“ funcA.cpp”

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
  num_x[2] = 10 + num_x[2];
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1]  1  2 13

“ funcB.cpp”

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcB(NumericVector& num_y) {
  packA::funcA(num_y);
}

> vec <- c(1,3)
> funcB(vec)
> vec
[1]  1  2 13

即使使用高级arma::vec构造函数创建具有共享内存的Armadillo矢量,只要输入是NumericVector

“ funcA.cpp”

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcA (NumericVector& num_x) {
  arma::vec x_int = arma::vec(num_x.begin(),3,false,false);
  x_int(2) = 10 + x_int(2);
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1]  1  2 13

> vec <- c(1,3)
> funcB(vec)
> vec
[1]  1  2 13

使用arma::vec尝试相同的操作不再有效。

“ funcA.cpp”

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(r,cpp)]]
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcA (arma::vec& x) {
  arma::vec x_int = arma::vec(x.begin(),false);
  x(2) = 10 + x(2);
}
> vec <- c(1,3)
> funcA(vec)
> vec
[1]  1  2 13

“ funcB.cpp”

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <packA.h>
using namespace Rcpp;

// [[Rcpp::export]]
void funcB(arma::vec& y) {
  packA::funcA(y);
}
> vec <- c(1,3)
> funcB(vec)
> vec
[1] 1 2 3

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)