c++ - Rcpp、C++11、 vector 和 Windows 的问题

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

我尝试在 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 + vector 运算

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

最佳答案

我怀疑你需要运行

  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> 

关于c++ - Rcpp、C++11、 vector 和 Windows 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25852814/

相关文章:

android - 应用程序可以读取 DNS TXT 记录吗?

r - 如何ddply嵌套列表

c++ - 是否有预处理器定义来区分 gcc 和 g++ 代码?

c++ - 静态局部变量的线程安全增量

c++ - DLL 到 Lib 的帮助

r - 如何将列表值列拆分为多列?

r - 将这些参数传递给另一个函数时如何将默认元素添加到 `...`

c++ - 捕获不可见线程的未处理异常

c# - 给定 shell 扩展 CLSID,如何找到实现 COM 可执行文件或 DLL,并检查其接口(interface)和成员?

windows - 从特定文件夹中获取特定文件