我正在尝试使用Rcpp定义一个加速的函数。情况如下:
我该如何解决这个问题?在其他帖子中看一点我得到的是我在某种程度上在FOO中包含头文件并在BAR中使用属性// [[Rcpp::depends(FOO)]]
,但我似乎错过了一些观点。关于如何做的任何提示?
最佳拉斯
编辑:感谢评论我喜欢Kevin Usheys的方法,并尝试实施它。然而,经过一些编码后,我意识到我实际上不需要来自FOO的函数,而是需要一个类及其公共函数。我想我不能做你为一堂课建议的技巧。我最终把这个类的源文件放在了BAR src目录中的FOO(不是最好的方法,因为我现在有两个版本的相同代码)。但是目前这个黑客对我有用。答案 0 :(得分:8)
我会推荐其中一个选项:
如果foo_a
和foo_b
足够简单,只需将inline
函数放在FOO
的标题中,并将这些标题放在FOO/inst/include/FOO.h
中。当您在Rcpp::depends(FOO)
上调用compileAttributes
(或load_all
)时,BAR
将包含此文件。
否则,请考虑使用R的注册模型注册函数。这是一项更多的工作,但这是可以忍受的。编写R扩展名有详细信息。我建议将所有注册逻辑放在FOO
中,以便客户端包BAR
只需要使用它。例如,我在foo_a
的标题中有FOO
这样的内容,例如在FOO/inst/include/FOO.h
:
#ifdef COMPILING_FOO
inline int foo_a(int x, double y, const std::string& z){
typedef int (*Fun)(int, double, const std::string&) ;
static Fun fun = (Fun)R_GetCCallable( "FOO", "foo_a" ) ;
return fun(x,y,z) ;
}
#else
// just declare it
int foo_a(int x, double y, const std::string& z) ;
#endif
以及foo_a
中某些.cpp
文件中FOO/src
的实际定义:
#define COMPILING_FOO
#include <FOO.h>
int foo_a(int x, double y, const std::string& z){
// do stuff
}
然后,您需要在foo_a
函数中使用R_RegisterCCallable
注册R_init_FOO
:
extern "C" void R_init_FOO( DllInfo* info ){
R_RegisterCCallable( "FOO", "foo_a", (DL_FUNC)foo_a );
}
答案 1 :(得分:4)
如果您不介意将Rcpp
介绍到包FOO
中,请另外选择 - 请跟随Section 3.5 of Rcpp-attributes并执行以下操作:
将// [[Rcpp::interfaces(cpp)]]
放在.cpp
源文件的顶部,其中包含您希望其他软件包可用的函数,
将// [[Rcpp::export]]
放在您要导出的功能之前,
在compileAttributes()
的包目录中调用FOO
以生成inst/include
中的文件,然后BAR
可以使用包// [[Rcpp::depends(FOO)]]
,
安装包FOO
。
如果你正确设置了这个,你应该可以使用这样的模板调用一个函数(假设foo_a
是FOO
中的导出函数):
// [[Rcpp::depends(FOO)]]
#include <Rcpp.h>
#include <FOO.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP some_function() {
return FOO::foo_a();
}
答案 2 :(得分:2)
RcppXts包只针对众所周知的xts包中的一系列函数执行此操作。
编辑:以下是来自xts的一些代码。
首先,xts :: src / init.c通过十几个声明(如
)进行注册R_RegisterCCallable("xts","do_is_ordered",(DL_FUNC) &do_is_ordered);
其次,xts :: inst / include / xtsApi.h为客户端包提供了一个标题,例如
SEXP attribute_hidden xtsIsOrdered(SEXP x, SEXP increasing, SEXP strictly) {
static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;
fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","do_is_ordered");
return fun(x, increasing, strictly);
}
第三,在像RcppXts这样的客户端软件包中,我们将此(使用Rcpp模块)定义为
function("xtsIsOrdered",
&xtsIsOrdered,
List::create(Named("x"),
Named("increasing") = true,
Named("strictly") = true),
"Tests whether object is (strictly) (increasing) ordered");
将它暴露给R.我们同样可以从C ++代码中调用C函数xtsIsOrdered
。
我删除了错误的早期评论,其中的功能必须符合'SEXP in,SEXP out'。