我正在尝试编写一些C++代码,使用Rcpp访问Windows中的某些操作系统级别的东西.一旦我包含windows.h或shlobj.h,我得到一堆编译错误.当我运行此代码时,它可以工作,所以我知道我正在获得一些基础知识.但是,当我取消注释与Windows相关的任何#include一行时,它都不起作用.
library(inline)
inc <- '
#include <iostream>
#include <stdio.h>
// #include <windows.h>
// #include <shlobj.h>
using namespace std;
'
src <- '
cout << "foo\\n";
printf("foo2\\n");
return Rcpp::wrap(20);
'
fun <- cxxfunction(signature(),
includes = inc,
src, plugin="Rcpp")
fun()
Run Code Online (Sandbox Code Playgroud)
注意:当我在RStudio中运行它时,输出cout和printf出现在控制台中,但是当我从Windows RGui运行它时,输出不会出现.我认为这与RGui处理文本输出的方式有关.
当我取消注释那些包含行时,我得到的错误如下所示:
In file included from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objbase.h:154:0,
from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/ole2.h:16,
from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/windows.h:94,
from file43c2f9e3518.cpp:22:
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:598:52: error: macro "Realloc" requires 3 arguments, but only 2 given
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:598:56: error: ISO C++ forbids initialization of member 'Realloc' [-fpermissive]
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:598:56: error: making 'Realloc' static [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
... 等等
有关如何使这项工作的任何提示?
更新:我设法让一些错误消失,但有些仍然存在.
我也Realloc从http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1242.html的一些建议中得到了错误.
该inc应改为:
inc <- '
#include <iostream>
#include <stdio.h>
// This is taken from http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1242.html
#include <R.h>
#undef Realloc
#define R_Realloc(p,n,t) (t *) R_chk_realloc( (void *)(p), (size_t)((n) * sizeof(t)) )
#include <shlobj.h>
using namespace std;
'
Run Code Online (Sandbox Code Playgroud)
我也通过传递-fpermissive给编译器来消除其他错误,如下问题:如何使用Rcpp和内联设置g ++编译器标志?
settings <- getPlugin("Rcpp")
settings$env$PKG_CXXFLAGS <- paste('-fpermissive',settings$env$PKG_CXXFLAGS,sep=' ')
fun <- cxxfunction(signature(), includes = inc,
src, plugin = "Rcpp",
settings = settings)
Sys.unsetenv('PKG_CXXFLAGS')
Run Code Online (Sandbox Code Playgroud)
但仍有一些错误:
In file included from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objbase.h:154:0,
from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/ole2.h:16,
from c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/shlobj.h:86,
from file43c267d3279.cpp:26:
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:599:25: error: expected identifier before '(' token
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:599:25: error: 'parameter' declared as function returning a function
c:\rtools\gcc-4.6.3\bin\../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/include/objidl.h:599:25: error: expected ')' before ',' token
Run Code Online (Sandbox Code Playgroud)
我想出了最后一个问题.它看起来像两个R和Windows头文件定义Realloc和Free,但有定义之间有些冲突.所以#undef在包含Windows标头之前我需要这两个宏.还有将-fpermissive标志传递给编译器的问题.
library(Rcpp)
library(inline)
inc <- '
// Taken from http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1242.html
// Undefine the Realloc macro, which is defined by both R and by Windows stuff
#undef Realloc
// Also need to undefine the Free macro
#undef Free
#include <windows.h>
#include <iostream>
#include <stdio.h>
using namespace std;
'
src <- '
cout << "foo\\n";
printf("foo2\\n");
return Rcpp::wrap(20);
'
# Need this for the Windows headers to work
# Set -fpermissive, from: http://stackoverflow.com/questions/7063265/how-to-set-g-compiler-flags-using-rcpp-and-inline
settings <- getPlugin("Rcpp")
settings$env$PKG_CXXFLAGS <- paste('-fpermissive',settings$env$PKG_CXXFLAGS,sep=' ')
fun <- cxxfunction(signature(),
includes = inc,
src,
plugin = "Rcpp",
settings = settings)
fun()
Run Code Online (Sandbox Code Playgroud)