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

How to export constants from C++ into R with Rcpp

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

我正在为某个 C 库编写一个包装器,并且在库的 headers 中定义了一些常量,这些常量可以在 API 调用中使用。因为我想在 R 代码中尽可能地模仿 API,所以我想将这些常量从 C 导出到 R。

可能有几种方法可以做到这一点,但一个简单的方法是导出一个 returns 常量值的函数并创建一个活动绑定到它。无论您使用的是 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

*/

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

因此,您可以编写一个 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 函数(定义 assignConstants() 函数和所有实际的包装器函数有用的东西)然后 运行 assignConstants() 函数实际定义全局环境中的常量。