Rcpp,使 DLL 中的 R 可以使用函数

Rcpp, making functions available to R from DLL

C++ 新手,我想使在 DLL 中编译的函数在 R 中可用。

到目前为止,我通过在 VisualStudio 中遵循 these steps,然后使用 dyn.load 从 R 到加载创建的 dll。

但是,我的 C++ 函数需要处理 R data.frame 对象,我不确定如何实现。我从 the Rcpp gallery 看到 Rcpp 可能包括 R 和 c++ 数据类型之间的某种转换,包括 data.frame 对象,但我不知道我是否可以使用 [=14 生成 dll =] 然后我可以使用 dyn.load.

将其包含在 R 中

Dirk Eddelbuettel 的回答,似乎可以使用 Rcpp 生成 "dynamic library",但是,当我尝试使用 rcpp.package.skeleton() 生成带有源 .cpp 文件的包。我想要一个 dll 的函数来自 the Rcpp gallery

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
DataFrame modifyDataFrame(DataFrame df) {
  // access the columns
  IntegerVector a = df["a"];
  CharacterVector b = df["b"];

  // make some changes
  a[2] = 42;
  b[1] = "foo";       
  // return a new data frame
  return DataFrame::create(_["a"]= a, _["b"]= b);
}

我试图将该代码粘贴到 VisualStudio 中以尝试生成该 DLL,但是我遇到了错误 "cannot find Rcpp.h",这是我意料之中的。

然后我在 RStudio 中按照以下步骤操作:

  1. 创建新项目/包
  2. 包含此 cpp 源文件作为此程序包的源文件
  3. include Rcpp 并输入Rcpp.package.skeleton("mypackage") 到目前为止,包文件夹中没有DLL
  4. 尝试通过转至 Build/Install 并重新启动在 RStudio 中构建包,但随后我收到一条错误消息 "Building R Packages needs installation of additional build tools, do you want to install them?" 但是我已经安装了 RbuildTools 3.4,当我单击 "YES" 在 RStudio 中没有任何反应。

PS: 很高兴听到其他方法,但这里应尽可能使用 DLL 格式。非常感谢任何信息,因为我基本上不知道 Rcpp 或 C++ 是如何工作的

以下似乎有效:

  1. 来自 R,运行 Rcpp.package.skeleton("dfcpp4", cpp_files="modifyDataFrame.cpp")。需要第二个参数才能使用 dyn.loaddll 获得 modifyDataFrame 函数。
  2. 从命令行 运行 R CMD build dfcpp4
  3. 运行 R CMD check dfcpp4 --no-manual 来自命令行。
  4. dll 文件现在存在于 src-x64 文件夹中

我现在可以使用

调用此函数
dyn.load("dfcpp4/src-x64/dfcpp4.dll")
df <- data.frame(a = c(1, 2, 3),
                 b = c("x", "y", "z"))
.Call("_dfcpp4_modifyDataFrame", df)
   a   b
1  1   x
2  2 foo
3 42   z

我不明白为什么在这种情况下应该使用 .Call 而不是 .C...

您需要弄清楚为什么您的设置被冲洗掉了。这 意味着简单 而且很简单。观看:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { IntegerVector a = df["a"]; CharacterVector b = df["b"]; a[2] = 42; b[1] = "foo"; return DataFrame::create(Named("a")=a, Named("b")=b); } ')                  
R> df <- data.frame(a=1:3, b=letters[24:26])                                                                                                                                                                       
R> df                                                                                                                                                                                                              
  a b                                                                                                                                                                                                              
1 1 x                                                                                                                                                                                                              
2 2 y                                                                                                                                                                                                              
3 3 z                                                                                                                                                                                                              
R> modDF(df)                                                                                                                                                                                                       
   a   b                                                                                                                                                                                                           
1  1   x                                                                                                                                                                                                           
2  2 foo                                                                                                                                                                                                           
3 42   z                                                                                                                                                                                                           
R>      

现在,我显然不建议在一个很长的一行中这样写。 您已经在正确的轨道上了 设置包。但是你需要弄清楚是什么阻碍了你的工具。

并且作为 PS 上面的单行缩进更好:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { \
      IntegerVector a = df["a"]; \
      CharacterVector b = df["b"]; \
      a[2] = 42;  \
      b[1] = "foo"; \ 
      return DataFrame::create(Named("a")=a, Named("b")=b); \
    } ')