如何使用Rcpp将常量从C ++导出到R.

时间:2016-04-21 18:15:36

标签: r rcpp

使用Rcpp将一些常量从C ++代码导出到R的最正确方法是什么?

我正在为一些C库编写一个包装器,并且在库的头文件中定义了一些可以在API调用中使用的常量。由于我想在R代码中尽可能接近地模仿API,我想将这些常量从C导出到R.

2 个答案:

答案 0 :(得分:2)

可能有两种方法可以做到这一点,但一种简单的方法是导出一个返回常量值并创建一个活动绑定的函数。无论您使用的是R函数还是C / C ++函数,该机制都可以正常工作,即使在删除基础函数后它似乎也可以工作:

#include <Rcpp.h>

// [[Rcpp::export]]
double MyConstant() {
    return 1.54;
}

/***R

MyConstant2 <- function() 1.54

makeActiveBinding("my_constant", MyConstant, .GlobalEnv)
makeActiveBinding("my_constant2", MyConstant2, .GlobalEnv)

my_constant
#[1] 1.54

my_constant2
#[1] 1.54

inherits(try(my_constant <- 2.5, TRUE), "try-error")
#[1] TRUE 

inherits(try(my_constant2 <- 2.5, TRUE), "try-error")
#[1] TRUE

rm(MyConstant, MyConstant2)

my_constant
#[1] 1.54

my_constant2
#[1] 1.54

inherits(try(my_constant <- 2.5, TRUE), "try-error")
#[1] TRUE 

inherits(try(my_constant2 <- 2.5, TRUE), "try-error")
#[1] TRUE

*/

答案 1 :(得分:2)

在Rcpp代码中,您可以作为Rcpp Environment对象访问正在运行的R会话中存在的所有R环境。然后,您可以通过对象读/写条目。

所以你可以做的是写一个Rcpp函数,它将条目分配给底层头文件中定义的常量。当然,您必须在函数的编译中包含头文件才能使其工作。

示例:

library(Rcpp);
cppFunction(
    includes='#define A 3', ## replace this with includes='#include "someheader.h"'
    'void assignConstants() { Environment ge = Environment::global_env(); ge["A"] = A; }'
);
A;
## Error: object 'A' not found
assignConstants();
A;
## [1] 3

当包装器的用户加载包装器时,加载过程都可以通过cppFunction()调用定义Rcpp函数(定义{{​​1}}函数和所有有用的实际包装器函数然后运行assignConstants()函数来实际定义全局环境中的常量。