将Rcpp与特定于Windows的包含一起使用

wch*_*wch 8 r rcpp

我正在尝试编写一些C++代码,使用Rcpp访问Windows中的某些操作系统级别的东西.一旦我包含windows.hshlobj.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中运行它时,输出coutprintf出现在控制台中,但是当我从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)

... 等等

有关如何使这项工作的任何提示?


更新:我设法让一些错误消失,但有些仍然存在.

我也Reallochttp://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)

wch*_*wch 5

我想出了最后一个问题.它看起来像两个R和Windows头文件定义ReallocFree,但有定义之间有些冲突.所以#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)

  • 通过 http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2018-September/010096.html 我今天了解到添加`-DSTRICT_R_HEADERS`就足够了。这样,R 头文件就不会首先定义这些宏。 (2认同)