假设我想包装一些 C 或 C++ 代码,其中包含无法通过 Rcpp 自动映射到 R 类型的数组或向量,但我需要将其传递给可输出有效 R 对象的 C/C++ 函数。例如:
typedef union {
size_t val_sizet;
long double val_longdbl;
} weird_struct
std::vector<weird_struct> an_unmappable_obj;
an_unmappable_obj.resize(2);
an_unmappable_obj[0].val_sizet = 1e20;
an_unmappable_obj[1].val_longdbl = 1.5 * 1e20;
由于这是一个无法转换为任何 R 原生类型的向量,我想知道如何在 R/Rcpp 中返回并处理这些对象,使得向量(或包含相同的值)可以通过 saveRDS
进行序列化,并在 readRDS
之后恢复其值。
我猜一种方法是通过 memcpy 将对象的内容转换为某种类型的 C++ 向量,该向量可以转换为 Rcpp 的“NumericVector”或类似类型,然后强制-在需要使用时将其第一个元素转换为所需 C 类型的数组,但我想知道是否有更好的解决方案。
最佳答案
如果您只想保存 C++ 数据以供稍后在同一 session 中使用,最简单的方法是使用外部指针。例如:
// [[Rcpp::export]]
Rcpp::XPtr< std::vector<double> > xptr_example() {
std::vector<double> * x = new std::vector<double>(10);
Rcpp::XPtr< std::vector<double> > p(x, true);
return p;
}
如果您仍然只想序列化,有很多选项,但您必须编写一些额外的自定义代码。
正如您所说,您可以将 cast
和 memcpy
转换为 R 向量(使用 RawVector
而不是 NumericVector
),但你必须小心,你的类只有“普通的旧数据”,没有像指针或文件处理程序这样的特殊内容。
关于R:如何序列化堆中的 C/C++ 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55893971/