【问题标题】:Problems with Rcpp, C++11, vectors and WindowsRcpp、C++11、向量和 Windows 的问题
【发布时间】:2014-09-15 16:40:32
【问题描述】:

我尝试在 64 位 Windows 上将 Rcpp 与 C++11 一起使用。我关注https://stackoverflow.com/a/25456836 并使用 gcc 4.8.1 与 R 3.1.1 和 Rcpp 0.11.2。

使用 C++ 文件simpleProd.cpp

#include <vector>

// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int simpleProd(std::vector<int> vec) {

  vec.push_back(5);

  int prod = 1;
  for (int &x : vec) {       // loop over all values of vec
    prod *= x;              // access each elem., comp. product
  }  
  return prod;
}

我在 R 中尝试过

library("Rcpp")
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
unlink("mypkg", recursive = TRUE)
Rcpp.package.skeleton("mypkg", cpp_files = "simpleProd.cpp", 
                      example_code = FALSE)
install.packages("mypkg", repos = NULL, type = "source", 
                 INSTALL_opts = "--no-multiarch")
library(mypkg)

没有问题,但如果我运行

simpleProd(1:5)

结果是

Error in .Call("mypkg_simpleProd", PACKAGE = "mypkg", vec) : 
  "mypkg_simpleProd" not available for .Call() for package "mypkg"

如果我只是使用

  sourceCpp("simpleProd.cpp")
  simpleProd(1:5)

没有问题。如果vec.push_back(5); 被删除或者没有使用 C++11 就没有问题。在 Linux 和 Mac 上没有问题,最后在 32 位 Windows(使用相应的工具链)上没有问题。

有什么想法吗?谢谢!

编辑:澄清:问题仅发生在特殊情况下:

64位Windows + Rcpp + Package + C++11 + 矢量运算

如果我更改其中之一,它会起作用。

【问题讨论】:

    标签: c++ windows r c++11 rcpp


    【解决方案1】:

    我怀疑你需要运行

      compileAttributes("mypkg")          # or setwd() into the directory first
    

    生成属性。

    骨架包就是这样做的。如果您在 RStudio 中工作,它也是半自动的。

    编辑 或者更明确地说,当您将Rcpp.package.skeleton() 函数与提供的文件一起使用时,我们可能不会为您运行compileAttributes()。这是一个错误——我会调查的。但是您可以通过手动运行该函数来修复它。

    编辑 2: 我对 compileAttributes() 的需求可能是错误的。您的示例对我有用(使用 Rcpp 的当前 GitHub 源)。但是,我确实必须启用 C++11 编译——我通过~/.R/Makevars 中的用户范围的CXXFLAGS 进行了编译。骨架代码不会从提供的文件中使用的插件推断出需要这个。您也可以手动编辑DESCRIPTIONsrc/Makevars 并手动添加。

    编辑 3: 没有问题。在 Windows 上,您 i) 必须降级 C++11 编译器选项,因为编译器较旧(这不是我们可以控制的),并且 ii) 我还删除了您排除多架构的约束。然后一切正常,见下文。这是运行当前 R 和当前软件包的标准 Windows 7 机器。

    R> setwd("C:/TEMP")
    R> library(Rcpp)
    R> Sys.setenv("PKG_CPPFLAGS"="-std=c++0x")
    R> Rcpp.package.skeleton("mypkg", cpp_files = "simpleProd.cpp", example_code = FALSE)
    Creating directories ...
    Creating DESCRIPTION ...
    Creating NAMESPACE ...
    Creating Read-and-delete-me ...
    Saving functions and data ...
    Making help files ...
    Done.
    Further steps are described in './mypkg/Read-and-delete-me'.
    
    Adding Rcpp settings
     >> added Imports: Rcpp
     >> added LinkingTo: Rcpp
     >> added useDynLib directive to NAMESPACE
     >> added importFrom(Rcpp, evalCpp) directive to NAMESPACE
     >> copied simpleProd.cpp to src directory
    R> install.packages("mypkg", repos = NULL, type = "source")
    Installing package into ‘c:/opt/R-library’
    (as ‘lib’ is unspecified)
    * installing *source* package 'mypkg' ...
    ** libs
    
    *** arch - i386
    g++ -m32 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x   -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c RcppExports.cpp -o RcppExports.o
    g++ -m32 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x   -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c simpleProd.cpp -o simpleProd.o
    g++ -m32 -shared -s -static-libgcc -o mypkg.dll tmp.def RcppExports.o simpleProd.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/i386 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/opt/R-CURR~1/bin/i386 -lR
    installing to c:/opt/R-library/mypkg/libs/i386
    
    *** arch - x64
    g++ -m64 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x   -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c RcppExports.cpp -o RcppExports.o
    g++ -m64 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x   -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include"     -O2 -Wall  -mtune=core2 -c simpleProd.cpp -o simpleProd.o
    g++ -m64 -shared -s -static-libgcc -o mypkg.dll tmp.def RcppExports.o simpleProd.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/opt/R-CURR~1/bin/x64 -lR
    installing to c:/opt/R-library/mypkg/libs/x64
    ** R
    ** preparing package for lazy loading
    ** help
    Warning: C:/TEMP/mypkg/man/mypkg-package.Rd:30: All text must be in a section
    Warning: C:/TEMP/mypkg/man/mypkg-package.Rd:31: All text must be in a section
    *** installing help indices
    ** building package indices
    ** testing if installed package can be loaded
    *** arch - i386
    *** arch - x64
    * DONE (mypkg)
    R> library(mypkg)
    R> simpleProd(1:5)
    [1] 600
    R> 
    

    【讨论】:

    • 谢谢德克。不幸的是,它仍然无法正常工作。我最初使用MakevarsMakevars.win,只是将其替换为Sys.setenv("PKG_CXXFLAGS"="-std=c++11") 以简化示例。请注意,出现问题的唯一情况是:64bit Windows + Rcpp + Package + C++11 + vector operation
    • 让我们分开,好吗? 64 位 Windows 和向量操作与此无关。您“只是”选择使用 C++11 标准,Rcpp.package.skeleton() 不会自动识别(作为可选功能)——不多也不少。如果还有其他我遗漏的问题,请在列表中使用可重现的示例进行报告。
    • C++11 不是问题,设置了标志。我们不能把它分开,因为这是问题所在。可重现的示例在问题中,它适用于 Linux、Mac 和 Win32,但不适用于 Win64。
    • 而 C++11 可以通过将循环重写为标准 C/C++-1998 循环来轻松摆脱这里。现在 win64 和 win32 使用相同的(过时的)gcc 二进制文件。为什么win64会有所不同?同样,rcpp-devel 是一个更好的扩展讨论论坛,因为您将获得更多的知名度。
    • 是的,上面的例子可以在没有 C++11 的情况下重写。不幸的是,对于我真正的包裹,情况并非如此。再次感谢您,我将在 rcpp-revel 上发布此内容。
    猜你喜欢
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多