【问题标题】:Building package with Rcpp, generated .h file missing header使用 Rcpp 构建包,生成的 .h 文件缺少标头
【发布时间】:2015-04-12 13:29:54
【问题描述】:

我目前正在 RStudio 中构建一个使用 Rcpp 的包。我已经定义了以下 .cpp 文件,它适用于Rcpp::sourceCpp

// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::interfaces(r, cpp)]]
#include <Rcpp.h>
#include <unordered_set>
using namespace Rcpp;

// [[Rcpp::export]]
std::unordered_set<int> traverse_cor(NumericMatrix x, float maxcor) {
  std::unordered_set<int> elements;
  int ncol = x.ncol();
  for(int i = 0; i < ncol; i++) {
    for(int j = 0; j < ncol; j++) {
      if(i < j) {
        if(x(i, j) > maxcor && x(i, j) < 1){
          elements.insert(i + 1); 
        }
      }
    }
  }
  return elements;
}

我正在遵循herehere 的指示。接下来我打电话给Rcpp::compileAttributes()。这会产生以下文件:

  • src/RcppExports.cpp
  • R/RcppExports.R
  • inst/include/mypackage.h
  • inst/include/mypackage_RcppExports.h

生成的 mypackage_RcppExports.h 文件如下所示:

// This file was generated by Rcpp::compileAttributes
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#ifndef __gwassim_RcppExports_h__
#define __gwassim_RcppExports_h__

#include <Rcpp.h>

namespace gwassim {

    using namespace Rcpp;

    namespace {
        void validateSignature(const char* sig) {
            Rcpp::Function require = Rcpp::Environment::base_env()["require"];
            require("gwassim", Rcpp::Named("quietly") = true);
            typedef int(*Ptr_validate)(const char*);
            static Ptr_validate p_validate = (Ptr_validate)
                R_GetCCallable("gwassim", "gwassim_RcppExport_validate");
            if (!p_validate(sig)) {
                throw Rcpp::function_not_exported(
                    "C++ function with signature '" + std::string(sig) + "' not found in gwassim");
            }
        }
    }

    inline std::unordered_set<int> traverse_cor(NumericMatrix x, float maxcor) {
        typedef SEXP(*Ptr_traverse_cor)(SEXP,SEXP);
        static Ptr_traverse_cor p_traverse_cor = NULL;
        if (p_traverse_cor == NULL) {
            validateSignature("std::unordered_set<int>(*traverse_cor)(NumericMatrix,float)");
            p_traverse_cor = (Ptr_traverse_cor)R_GetCCallable("gwassim", "gwassim_traverse_cor");
        }
        RObject __result;
        {
            RNGScope __rngScope;
            __result = p_traverse_cor(Rcpp::wrap(x), Rcpp::wrap(maxcor));
        }
        if (__result.inherits("interrupted-error"))
            throw Rcpp::internal::InterruptedException();
        if (__result.inherits("try-error"))
            throw Rcpp::exception(as<std::string>(__result).c_str());
        return Rcpp::as<std::unordered_set<int> >(__result);
    }

}

#endif // __gwassim_RcppExports_h__

在尝试构建并重新加载包后,我收到以下错误 (1):

../inst/include/gwassim_RcppExports.h:27:12: 错误:'unordered_set' in 命名空间“std”没有命名类型

和(2)

RcppExports.cpp:12:1:错误:命名空间“std”中的“unordered_set”确实如此 不命名类型

我的 C++ 经验有限,但我的感觉是这些错误是由于 #include &lt;unordered_set&gt; 被省略而发生的。如何让这些自动生成的文件具有正确的标题?

我的 sessionInfo 如下:

Session info ----------------------------------------------------------------------
 setting  value                       
 version  R version 3.1.0 (2014-04-10)
 system   x86_64, mingw32             
 ui       RStudio (0.99.235)          
 language (EN)                        
 collate  English_United States.1252  
 tz       America/New_York            

Packages --------------------------------------------------------------------------
 package    * version    date       source                          
 devtools     1.7.0.9000 2015-02-11 Github (hadley/devtools@9415a8a)
 digest     * 0.6.4      2013-12-03 CRAN (R 3.1.0)                  
 memoise    * 0.2.1      2014-04-22 CRAN (R 3.1.0)                  
 mvtnorm      1.0-2      2014-12-18 CRAN (R 3.1.2)                  
 Rcpp         0.11.4     2015-01-24 CRAN (R 3.1.2)                  
 roxygen2   * 4.1.0      2014-12-13 CRAN (R 3.1.2)                  
 rstudioapi * 0.2        2014-12-31 CRAN (R 3.1.2)                  
 stringr    * 0.6.2      2012-12-06 CRAN (R 3.0.0)   

我的 g++ 版本是 4.6.3,包含在 Windows 的 RTools 包中。我启用了 C++11 功能,具有以下功能: Sys.setenv("PKG_CXXFLAGS"="-std=c++0x")

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    这是一个挑剔的。我想你想要Rcpp Attributes 小插图的第 3.5.2 节和这个技巧:

    Package.h 文件除了包含 Package_RcppExports.h 标头。这样做是为了使包 作者可以将Package.h 标头替换为自定义标头 并且仍然能够包含自动生成的导出 (下一节将提供有关此操作的详细信息)。

    顺便说一句,我想我也说服你创建一个包而不是仅仅依赖sourceCpp() :)

    编辑: 哇!!我忽略了

    std::unordered_set<int> traverse_cor(NumericMatrix x, float maxcor) 
    

    可能不是一个自动包装的函数。您可能需要将您的集合转换为向量(或列表或...),以获得自然匹配到 R 中的类型之一。

    【讨论】:

    • 好的,我试过了。我做了以下事情:1)编辑 Package.h 标头以具有 #include &lt;unordered_set&gt; 并删除顶部的令牌和 2)尝试构建并重新加载包。似乎摆脱了 RcppExports.cpp 的错误,但我仍然得到../inst/include/gwassim_RcppExports.h:27:12: error: 'unordered_set' in namespace 'std' does not name a type
    • 看起来我需要更改 Package.h 文件中标题的顺序。这样做之后,我现在收到一个不同的错误,原来的错误消失了:include/Rcpp/internal/Exporter.h:31:31: error: invalid conversion from 'SEXP' to 'long long unsigned int' [-fpermissive]
    • 为此,最简单的解决方法是在包中打开 C++11 支持。
    • 我相信我正在使用 Sys.setenv("PKG_CXXFLAGS"="-std=c++0x") 做这件事,我在尝试构建包之前运行它。
    • 为了简单起见,我会在src/Makevars 中添加CXX_STD = CXX11
    猜你喜欢
    • 1970-01-01
    • 2019-10-24
    • 2015-07-31
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多