使用Rcpp将某些常量从C++代码导出到R中的最正确方法是什么?如何使用Rcpp将常量从C++导出为R
我正在为一些C库编写包装器,并且在库调用中可能会使用API头中定义的一些常量。因为我想在R代码中尽可能接近地模拟API,所以我想将这些常量从C中导出到R.
使用Rcpp将某些常量从C++代码导出到R中的最正确方法是什么?如何使用Rcpp将常量从C++导出为R
我正在为一些C库编写包装器,并且在库调用中可能会使用API头中定义的一些常量。因为我想在R代码中尽可能接近地模拟API,所以我想将这些常量从C中导出到R.
在RCPP代码,您可以访问所有存在于正在运行的R会话中的R环境作为Rcpp Environment
对象。然后您可以通过该对象读取/写入条目。
所以你可以做的就是编写一个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()
电话(定义两个assignConstants()
功能和所有的实际包装函数是一举两得定义RCPP功能有用的东西),然后运行assignConstants()
函数来实际定义全局环境中的常量。
我不知道为什么这是downvoted。看起来像许多可能和合理的方法之一。 –
可能有几种方法可以做到这一点,但一种简单的方法是导出一个函数,返回一个常量值并为其创建一个活动绑定。该机制将很好的工作无论您是使用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
*/
从狭义上讲,您可以通过'.onLoad()'或'.onAttach()'在R代码中定义它们。无论是在R代码中,还是通过循环来自C++的元素通过辅助函数循环。做一些自动化更难。我有时候希望将它用于'enum'类型,但也没有好的解决方案。 –