C++ 从sourceCpp移动到带有Rcpp的包
我目前有一个C++ 从sourceCpp移动到带有Rcpp的包,c++,r,rcpp,C++,R,Rcpp,我目前有一个.cpp文件,可以使用sourceCpp()进行编译。正如预期的那样,相应的R函数被创建,代码按预期工作 这是: #include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] NumericVector exampleOne(NumericVector vectorOne, NumericVector vectorTwo){ NumericVector outputVector = vectorOne
.cpp
文件,可以使用sourceCpp()
进行编译。正如预期的那样,相应的R函数被创建,代码按预期工作
这是:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector exampleOne(NumericVector vectorOne, NumericVector vectorTwo){
NumericVector outputVector = vectorOne + vectorTwo;
return outputVector;
}
然后我(重新)构建了包,我得到了以下错误:
.Call(“exampleOne”、vectorOne、vectorwo、PACKAGE=“voteR”)中出现错误:
C符号名称“exampleOne”不在包“testPackage”的DLL中
有人知道我在获取用sourceCpp()编译的代码并将其用于包中时还需要做什么吗?
我应该注意到,我已经阅读了“编写一个使用Rcpp的包”,并且理解了其中介绍的基本结构。但是,在查看了
RcppExamples
源代码之后,vignettes中的结构似乎与示例包中使用的结构不完全相同。例如,没有使用.h文件。另外,vignette和源代码都没有使用[[Rcpp::export]]属性。这一切都使得我很难准确地找到我的错误所在。你是以假乱真
sourceCpp()
是一个新函数;这是我们称之为“Rcpp属性”的一部分,它有自己的小插曲(在软件包、我的网站和CRAN上都有相同的标题),您可能想阅读。它还详细介绍了如何将使用sourceCpp()
编译和运行的内容转换为一个包。这就是你想要的
在文档之间随意跳转对您没有帮助,在真正的源代码文档结束时,最好由包作者编写。或者换一种说法:您使用的是一个新功能,但旧文档没有反映它。尝试用Rcpp编写一个基本包(也可以从另一端开始编写)
最后,还有一个邮件列表…下面是我的“演练”,介绍如何从使用sourceCpp()过渡到使用Rcpp的包。如果有一个错误,请随时编辑此或让我知道,我会编辑它
[注意:我强烈建议在此过程中使用RStudio。]
因此,您已经了解了sourceCpp()的内容,现在需要构建一个包。这并不难,但可能有点棘手,因为关于使用Rcpp构建软件包的信息包括您想要的任何R软件包的详尽文档(但作为一个新手,这超出了您的想象),以及对新手敏感的介绍(可能会遗漏您碰巧需要的细节)
在这里,我使用oneCpp.cpp
和twoCpp.cpp
作为您将在包中使用的两个.cpp文件的名称
以下是我的建议:
答:首先,我假设您有一个使用sourceCpp()编译的theCppFile.cpp
版本,它可以按照您的预期工作。这不是必须的,但是如果您是Rcpp或包的新手,那么在转到下面更复杂的情况之前,最好确保您的代码在这种简单的情况下工作
B.现在使用Rcpp.package.skeleton()
或使用RStudio中的Project>Create Project>package w/Rcpp向导构建包(强烈建议)。您可以在或中找到有关使用Rcpp.package.skeleton()的详细信息。与Rcpp一起编写包的完整文档已经进入,但是这一假设假设您完全了解C++的方式,并且不使用新的“属性”方式来执行Rcpp。但是,如果您着手制作更复杂的软件包,这将是非常宝贵的
现在,您的包应该有一个如下所示的目录结构:
yourPackageName
- DESCRIPTION
- NAMESPACE
- \R\
- RcppExports.R
- Read-and-delete-me
- \man\
- yourPackageName-package.Rd
- \src\
- Makevars
- Makevars.win
- oneCpp.cpp
- twoCpp.cpp
- RcppExports.cpp
设置好所有内容后,如果使用RStudio,请执行“构建并重新加载”,如果不在RStudio中,请执行compileAttributes()
C.您现在应该在\R
目录中看到一个名为RcppExports.R
的文件。打开它,检查一下。在RcppExports.R
中,您应该看到\src
目录中所有.cpp
文件的R包装函数。很甜蜜,是吗
D) 尝试与您在cppfile.cpp中编写的函数相对应的R函数。它有用吗?如果是这样,那就继续吧
E) 现在,您只需在创建新的.cpp
文件时将其添加到\src
目录中,如otherCpp.cpp
。然后,您只需重新构建包,就会生成R包装并为您添加到RcppExports.R
。在RStudio中,这只是构建菜单中的“构建&重新加载”。如果不使用RStudio,则应运行compileAttributes()
简而言之,技巧是从包的根目录中调用compileAttributes()
。比如包foo
$ cd /path/to/foo
$ ls
DESCRIPTION man NAMESPACE R src
$ R
R> compileAttributes()
此命令将生成缺少的RcppExports.cpp
和RcppExports.R
。如果正确使用compileAttributes
,则无需自己创建R函数。但很大程度上取决于您如何创建包—RStudio和(开发版本的)devtools中的包开发工具将为您处理大部分细节。我的投票仍然是支持手工操作并理解所发生的事情—只需从rcpp.package.skeleton()开始
它有一个与属性一起使用的选项。谢谢你们两位。正如Hadley所说,我在意识到RcppExports.R文件包含所有相应的R函数(多亏了)之后,转储了R文件的“我的”版本。现在错误消失了。通过尝试创建我自己版本的R文件,它不知怎么搞砸了(可能是共享库?)。我认为就我的目的而言,RStudio路径现在是最好的。在将“编写使用Rcpp的包”中的一般信息应用于代码时,从头开始构建会让我犯很多错误。那里的所有代码都使用了“pre-attribute”方法。也都
$ cd /path/to/foo
$ ls
DESCRIPTION man NAMESPACE R src
$ R
R> compileAttributes()