简体   繁体   English

调用 Rcpp c++ function 从 R 代码在同一个 ZEFE90A8E604A7C840E88D03D6

[英]Call Rcpp c++ function from R code in the same package

I want to build an Rcpp package with C++ and R code.我想用 C++ 和 R 代码构建一个 Rcpp package 代码。 With the C++ code only (R code removed), everything compiles and works nicely and after building and loading the exported functions are callable as expected as仅使用 C++ 代码(已删除 R 代码),一切都可以编译并运行良好,并且在构建和加载导出的函数后可以按预期调用

<packageName>::<functionName>()

However, when including the R code with the call to the C++ code, I get an object not found error when building the package:但是,当包含 R 代码和对 C++ 代码的调用时,我得到一个 object 在构建 ZEFE8407A8DZ03ADD76A7 时未找到错误

R CMD build <packageName>
[...]
** R
** byte-compile and prepare package for lazy loading
Error in <functionName>() :
  object '_<packageName>_<functionName>' not found
Error: unable to load R code in package '<packageName>'

The error happens after the C++ code is successfully compiled.该错误发生在 C++ 代码编译成功后。

<functionName>()

is mapped to映射到

_<packageName>_<functionName>

in R/RcppExports.R as usual, but it does not appear that it can be loaded by the R code at build time.像往常一样在R/RcppExports.R中,但它似乎不能在构建时由 R 代码加载。

The structure of the package is as usual: package的结构和往常一样:

<packageName>
├── DESCRIPTION
├── man
│   ├── <functionName>.rd
│   └── <packageName>-package.rd
├── NAMESPACE
├── R
│   ├── <RCodeFileName>.R
│   └── RcppExports.R   
├── README.md
└── src
    ├── <C++CodeFileName>.cpp
    ├── <C++CodeFileName>.o
    ├── <packageName>.so
    ├── RCppExports.cpp
    ├── RCppExports.o
    └── symbols.rds

where the .o and .so files are produced when compiling the package.编译 package 时会生成.o.so文件。

The R file calls the function from the C++ file directly: R 文件直接从 C++ 文件中调用 function:

[other stuff]
[...]
<functionName>()

NAMESPACE file is also as usual: NAMESPACE文件也照常:

useDynLib(<packageName>, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")

This seems like a very simple and straight forward problem (calling C++ code from R code in an Rcpp package).这似乎是一个非常简单直接的问题(从 Rcpp 包中的 R 代码调用 C++ 代码)。 Nevertheless, I seem to be unable to find any indication of how this should be done.尽管如此,我似乎无法找到任何关于如何做到这一点的迹象。

Edit (Apr 8 2020): build vs. INSTALL编辑(2020 年 4 月 8 日): buildINSTALL

The problem will occur in every case for在每种情况下都会出现问题

R CMD INSTALL <packageName>_<version>.tar.gz

If the included help file如果包含的帮助文件

man/<packageName>-package.Rd

is built so that it forces installing the package to process help pages the error will already occur in构建它以强制installing the package to process help pages ,该错误已经发生在

R CMD build <packageName>

as described above.如上所述。

Edit (Apr 8 2020): Steps to reproduce with Rcpp.package.skeleton() (on Unix-like systems anyway)编辑(2020 年 4 月 8 日):使用Rcpp.package.skeleton()重现的步骤(无论如何在类 Unix 系统上)

Rscript -e 'Rcpp::Rcpp.package.skeleton("demo20200408")'
echo 'rcpp_hello_world()' > errorDemo/R/example.R
R CMD INSTALL errorDemo

You may want to slow dowm.你可能想放慢速度。 The Rcpp package itself comes with a demo package generator via the Rcpp.package.skeleton() function. The Rcpp package itself comes with a demo package generator via the Rcpp.package.skeleton() function. Run it!运行!

The compare piece by piece to what you have.逐个比较你所拥有的。

A second generator is e.g.第二个生成器是例如built into RStudio and available under the File -> New Project -> New directory -> Package with Rcpp menu options.内置在 RStudio 中,可在文件 -> 新项目 -> 新目录 -> Package 下使用 Rcpp 菜单选项。

Otherwise, hard to tell.否则,很难说。 Did you do anything funky to you function name?你对你 function 的名字做了什么时髦的事吗? Because these are mapped to R and C++ you have restrictions from both.因为这些映射到 RC++ ,所以您对两者都有限制。 Ie you cannot use a dot (as that would be a class method notation in C++).你不能使用点(因为那将是 C++ 中的 class 方法符号)。

Lastly, even when unexported the C++ function should be available from the installed and loaded package via three colons, ie mypkg:::myFun() .最后,即使未导出C++ function 也应该可以通过三个冒号从已安装和加载的 package 获得,mypkg:::myFun()

Lastly, quick demo:最后,快速演示:

Create it 创造它
edd@rob:/tmp$ Rscript -e 'Rcpp::Rcpp.package.skeleton("demo20200408")' Creating directories... Creating DESCRIPTION... Creating NAMESPACE... Creating Read-and-delete-me... Saving functions and data... Making help files... Done. Further steps are described in './demo20200408/Read-and-delete-me'. Adding Rcpp settings >> added Imports: Rcpp >> added LinkingTo: Rcpp >> added useDynLib directive to NAMESPACE >> added importFrom(Rcpp, evalCpp) directive to NAMESPACE >> added example src file using Rcpp attributes >> added Rd file for rcpp_hello_world >> compiled Rcpp attributes edd@rob:/tmp$
Install it 安装它
edd@rob:/tmp$ Rscript -e 'library(demo20200408); rcpp_hello_world()'
[[1]]
[1] "foo" "bar"

[[2]]
[1] 0 1

edd@rob:/tmp$ 
Run it 运行
edd@rob:/tmp$ Rscript -e 'library(demo20200408); rcpp_hello_world()' [[1]] [1] "foo" "bar" [[2]] [1] 0 1 edd@rob:/tmp$
And add an R function and call it too 并添加一个 R function 并调用它
edd@rob:/tmp$ echo 'r_hello_world <- function() cat("hi there\n")' > demo20200408/R/foo.R edd@rob:/tmp$ R CMD INSTALL demo20200408 * installing to library '/usr/local/lib/R/site-library' * installing *source* package 'demo20200408'... ** using staged installation ** libs make: Nothing to be done for 'all'. installing to /usr/local/lib/R/site-library/00LOCK-demo20200408/00new/demo20200408/libs ** R ** byte-compile and prepare package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded from temporary location ** checking absolute paths in shared objects and dynamic libraries ** testing if installed package can be loaded from final location ** testing if installed package keeps a record of temporary installation path * DONE (demo20200408) edd@rob:/tmp$ Rscript -e 'library(demo20200408); r_hello_world()' hi there edd@rob:/tmp$
Still no issue despite OP's claims 尽管 OP 声称仍然没有问题

In the most recent comment below it is claimed that the generated function cannot be called.在下面的最新评论中,声称生成的 function 无法调用。 That is false.那是错误的。

 edd@rob:/tmp$ editor demo20200408/R/foo.R # subst. fave editor here edd@rob:/tmp$ cat demo20200408/R/foo.R r_hello_world <- function() { cat("hi there\n") ignored <- rcpp_hello_world() NULL } edd@rob:/tmp$ R CMD INSTALL demo20200408 * installing to library '/usr/local/lib/R/site-library' * installing *source* package 'demo20200408'... ** using staged installation ** libs make: Nothing to be done for 'all'. installing to /usr/local/lib/R/site-library/00LOCK-demo20200408/00new/demo20200408/libs ** R ** byte-compile and prepare package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded from temporary location ** checking absolute paths in shared objects and dynamic libraries ** testing if installed package can be loaded from final location ** testing if installed package keeps a record of temporary installation path * DONE (demo20200408) edd@rob:/tmp$ Rscript -e 'library(demo20200408); r_hello_world()' hi there NULL edd@rob:/tmp$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM