Rcpp包使用Rcpp::traits::Exporter扩展类时R CMD build报错如何解决
问题原因
sourceCpp属于单文件编译逻辑,你写的自定义类、Exporter特化和导出函数都在同一个文件内,编译时可以找到所有声明;但R包构建时,Rcpp自动生成的src/RcppExports.cpp默认仅引入<Rcpp.h>,没有包含你的自定义foo::bar类和对应Exporter特化的声明,因此编译时报找不到类型的错误。
具体修改步骤
1. 拆分头文件与实现
在包的src目录下新建头文件foobar.h,写入所有类型声明代码:
#ifndef FOOBAR_H #define FOOBAR_H #include <RcppCommon.h> // 前向声明类 namespace foo { class bar; } // 前向声明Rcpp::as<> Exporter template <> class Rcpp::traits::Exporter<foo::bar>; #include <Rcpp.h> // 完整类声明 namespace foo { class bar { public: Rcpp::NumericVector x; bar(Rcpp::NumericVector x) : x(x) {}; }; } // Rcpp exporter特化实现 namespace Rcpp { namespace traits { template <> class Exporter<foo::bar> { Rcpp::NumericVector x_; public: Exporter(SEXP x) : x_(x) {} foo::bar get() { return foo::bar(x_); } }; } } #endif
修改原foobar.cpp,仅保留头文件引入和导出函数:
#include "foobar.h" //[[Rcpp::export]] Rcpp::NumericVector test(foo::bar& A) { return A.x; }
2. 配置Rcpp自动引入自定义头文件
在src目录下新建和你的包名同名的预处理头文件,假设你的包名为testpkg,则文件名为testpkg_preproc.h,写入以下内容:
#include "foobar.h"
Rcpp在执行compileAttributes()生成RcppExports.cpp时,会自动将该头文件的内容添加到RcppExports.cpp的最开头,编译时就能找到自定义类的声明。
3. 重新编译验证
执行Rcpp::compileAttributes()更新导出文件,再重新运行R CMD build、R CMD check即可正常编译通过。
内容的提问来源于stack exchange,提问作者zdebruine
相关产品推荐
相关产品推荐

