比方说,我想在R中构建一个非常简单的程序包,用于包装c ++代码。
我的测试项目将称为 bananas 。
比方说,我有一个名为“ 香蕉”的文件夹,其中还有另外两个文件夹,一个名为 c ++ ,另一个名为 R 。
在 c ++ 文件夹中,我有一个名为 include 的文件夹,其中包含 bananas.hpp 头文件(具有类定义):>
#ifndef BANANAS_H
#define BANANAS_H
class Bananas
{
public:
void add_banana();
int get_bananas();
protected:
int number_of_bananas;
};
#endif
在 include 外部,有一个 bananas.cpp 文件,该文件实现 bananas.hpp 的方法:< / p>
#include "include/bananas.hpp"
using namespace std;
void Bananas::add_banana(){
// Return False if edge already existed
number_of_bananas ++;
}
int Bananas::get_bananas(){
return number_of_bananas;
}
现在在我的 R 文件夹中,有一个 wrapper.cpp 文件,该文件使用Rcpp库将R内的c ++类导出为模块:
#include <Rcpp.h>
#include "include/bananas.hpp"
using namespace Rcpp;
RCPP_EXPOSED_CLASS(Bananas)
RCPP_MODULE(Bananas_cpp){
class_<Bananas>("BananasCPP")
.default_constructor()
.method("add_banana", &Bananas::add_banana)
.method("get_bananas", &Bananas::get_bananas)
;
}
请注意,目前#include "include/bananas.hpp"
并不代表任何含义,但是将来此文件将添加到源代码中。
最后,我主要关心的是该类的R包装器所在的位置:
require(R6)
library(Rcpp)
# For exposing the error
print(ls(all.names = TRUE))
# Load Module
bcpp <- Module("Bananas_cpp", PACKAGE="RBananasC", mustStart = TRUE)$BananasCPP
Bananas <- R6Class("Bananas", list(
bn = new(bcpp),
print_bananas = function() {print(self$bn$get_bananas())},
banana_tree = function(d) {
for(row in 1:d){
self$bn$add_banana()
}
}
))
现在在我的主目录中运行 setup.R 文件时,该文件如下所示:
require(Rcpp)
# Make a base package
unlink("RBananasC", recursive=TRUE)
Rcpp.package.skeleton(name = "RBananasC", list = character(),
path = ".", force = FALSE,
cpp_files = c("bananas/R/wrapper.cpp", "bananas/c++/bananas.cpp", "bananas/c++/include/bananas.hpp"))
dir.create("RBananasC/src/include")
file.rename("RBananasC/src/bananas.hpp", "RBananasC/src/include/bananas.hpp")
install.packages("RBananasC", repos=NULL, type="source")
# See that Bananas_cpp works
library(RBananasC) #Without this line it doesn't work
print(Module("Bananas_cpp", PACKAGE="RBananasC", mustStart = TRUE)$BananasCPP)
bcpp <- Module("Bananas_cpp", PACKAGE="RBananasC", mustStart = TRUE)$BananasCPP
ban <- new(bcpp)
ban$add_banana()
print(ban$get_bananas())
# Make the desired package
unlink("RBananas", recursive=TRUE)
Rcpp.package.skeleton(name = "RBananas", list = character(),
path = ".", force = FALSE,
code_files = c("bananas/R/bananas.R"), cpp_files = c("bananas/R/wrapper.cpp", "bananas/c++/bananas.cpp", "bananas/c++/include/bananas.hpp"))
dir.create("RBananas/src/include")
file.rename("RBananas/src/bananas.hpp", "RBananas/src/include/bananas.hpp")
install.packages("RBananas", repos=NULL, type="source")
我的 bananas.R 文件内部有一个非常奇怪的行为,这与以下事实有关:我的软件包的 Bananas_cpp 模块不可见,因此我无法安装后访问类 BananasCPP 。 另一方面,如果忽略文件 bananas.R ,则可以从软件包 RBananasC Bananas_cpp 的模块中导入 BananasCPP / strong>,我是用 Rcpp.package.skeleton 创建的。
总结整个文件结构如下:
.
├── bananas
│ ├── c++
│ │ ├── bananas.cpp
│ │ └── include
│ │ └── bananas.hpp
│ └── R
│ ├── bananas.R
│ └── wrapper.cpp
└── setup.R
要演示我的问题,只需运行 setup.R 。
我遵循的是标准tutorial,但是我找不到从 Bananas_cpp 模块中如何加载 BananasCPP 类的任何信息。 strong> Bananas.R 包装功能 Bananas ,同时在互联网上搜索几天。该文件未出现在包内部活动环境的名称空间中,因此我认为应该解决的问题:“我应该添加哪些命令,以及在 Bananas_cpp 模块的当前名称空间中显示该模块的位置。包装”。
当然,这是我从遇到的一个实际问题中得出的结论。 非常感谢您的支持!