从同一包中的 R 代码调用 Rcpp c++ 函数
Call Rcpp c++ function from R code in the same package
我想用 C++ 和 R 代码构建一个 Rcpp 包。仅使用 C++ 代码(删除 R 代码),所有内容都可以编译并运行良好,并且在构建和加载导出函数后可以按预期调用
<packageName>::<functionName>()
但是,在调用 C++ 代码时包含 R 代码时,我在构建包时遇到找不到对象的错误:
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>'
错误发生在C++代码编译成功后。
<functionName>()
映射到
_<packageName>_<functionName>
像往常一样在 R/RcppExports.R
中,但它似乎不能在构建时由 R 代码加载。
包的结构和往常一样:
<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
编译包时生成.o
和.so
文件的地方。
R文件直接调用C++文件中的函数:
[other stuff]
[...]
<functionName>()
NAMESPACE
文件也照常:
useDynLib(<packageName>, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")
这似乎是一个非常简单直接的问题(从 Rcpp 包中的 R 代码调用 C++ 代码)。尽管如此,我似乎无法找到任何关于应该如何完成的指示。
编辑(2020 年 4 月 8 日):build
对比 INSTALL
在
的每种情况下都会出现该问题
R CMD INSTALL <packageName>_<version>.tar.gz
如果包含帮助文件
man/<packageName>-package.Rd
的构建是为了强制 installing the package to process help pages
错误将在
中发生
R CMD build <packageName>
如上所述。
编辑(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
你可能想放慢速度。 Rcpp 包本身 通过 Rcpp.package.skeleton()
函数附带了一个演示包生成器 。 运行啦!
逐个比较你所拥有的。
第二个生成器 例如 内置于 RStudio 中,可在文件 -> 新项目 -> 新目录 -> Package with Rcpp 菜单选项下使用。
否则不好说。你对你的函数名做了什么奇怪的事吗?因为它们映射到 R 和 C++,所以您对两者都有限制。 即 你不能使用点(因为在 C++ 中那将是 class 方法符号)。
最后,即使 未导出 C++ 函数也应该可以通过三个冒号从安装和加载的包中获得,即 mypkg:::myFun()
.
最后,快速演示:
创建它
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$
安装它
edd@rob:/tmp$ R CMD INSTALL demo20200408
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘demo20200408’ ...
** using staged installation
** libs
ccache g++ -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O3 -Wall -pipe -pedantic -c RcppExports.cpp -o RcppExports.o
ccache g++ -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O3 -Wall -pipe -pedantic -c rcpp_hello_world.cpp -o rcpp_hello_world.o
ccache g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o demo20200408.so RcppExports.o rcpp_hello_world.o -L/usr/lib/R/lib -lR
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$
运行它
edd@rob:/tmp$ Rscript -e 'library(demo20200408); rcpp_hello_world()'
[[1]]
[1] "foo" "bar"
[[2]]
[1] 0 1
edd@rob:/tmp$
并添加一个 R 函数并调用它
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$
尽管 OP 声称仍然没有问题
在下面的最新评论中声称无法调用生成的函数。那是错误的。
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$
我想用 C++ 和 R 代码构建一个 Rcpp 包。仅使用 C++ 代码(删除 R 代码),所有内容都可以编译并运行良好,并且在构建和加载导出函数后可以按预期调用
<packageName>::<functionName>()
但是,在调用 C++ 代码时包含 R 代码时,我在构建包时遇到找不到对象的错误:
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>'
错误发生在C++代码编译成功后。
<functionName>()
映射到
_<packageName>_<functionName>
像往常一样在 R/RcppExports.R
中,但它似乎不能在构建时由 R 代码加载。
包的结构和往常一样:
<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
编译包时生成.o
和.so
文件的地方。
R文件直接调用C++文件中的函数:
[other stuff]
[...]
<functionName>()
NAMESPACE
文件也照常:
useDynLib(<packageName>, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")
这似乎是一个非常简单直接的问题(从 Rcpp 包中的 R 代码调用 C++ 代码)。尽管如此,我似乎无法找到任何关于应该如何完成的指示。
编辑(2020 年 4 月 8 日):build
对比 INSTALL
在
的每种情况下都会出现该问题R CMD INSTALL <packageName>_<version>.tar.gz
如果包含帮助文件
man/<packageName>-package.Rd
的构建是为了强制 installing the package to process help pages
错误将在
R CMD build <packageName>
如上所述。
编辑(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
你可能想放慢速度。 Rcpp 包本身 通过 Rcpp.package.skeleton()
函数附带了一个演示包生成器 。 运行啦!
逐个比较你所拥有的。
第二个生成器 例如 内置于 RStudio 中,可在文件 -> 新项目 -> 新目录 -> Package with Rcpp 菜单选项下使用。
否则不好说。你对你的函数名做了什么奇怪的事吗?因为它们映射到 R 和 C++,所以您对两者都有限制。 即 你不能使用点(因为在 C++ 中那将是 class 方法符号)。
最后,即使 未导出 C++ 函数也应该可以通过三个冒号从安装和加载的包中获得,即 mypkg:::myFun()
.
最后,快速演示:
创建它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$
安装它
edd@rob:/tmp$ R CMD INSTALL demo20200408
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘demo20200408’ ...
** using staged installation
** libs
ccache g++ -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O3 -Wall -pipe -pedantic -c RcppExports.cpp -o RcppExports.o
ccache g++ -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O3 -Wall -pipe -pedantic -c rcpp_hello_world.cpp -o rcpp_hello_world.o
ccache g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o demo20200408.so RcppExports.o rcpp_hello_world.o -L/usr/lib/R/lib -lR
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$
运行它
edd@rob:/tmp$ Rscript -e 'library(demo20200408); rcpp_hello_world()'
[[1]]
[1] "foo" "bar"
[[2]]
[1] 0 1
edd@rob:/tmp$
并添加一个 R 函数并调用它
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$
尽管 OP 声称仍然没有问题
在下面的最新评论中声称无法调用生成的函数。那是错误的。
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$