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

时间:2012-07-21 01:26:21

标签: 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()

注意:当我在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]

......等等

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


更新:我设法让一些错误消失,但仍有一些错误。

我还是通过http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1242.html

的一些建议得到了Realloc错误

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;
'

我还通过将-fpermissive传递给编译器来解决其他错误,如此问题: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)
Sys.unsetenv('PKG_CXXFLAGS')

但仍有一些错误:

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

3 个答案:

答案 0 :(得分:6)

我想出了最后一个问题。看起来R和Windows标头都定义ReallocFree,但定义之间存在一些冲突。因此,在包含Windows标头之前,我需要#undef这两个宏。还有将-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()

答案 1 :(得分:3)

在第一次近似时,你只能用Rcpp构建,如果你可以用R本身构建,因为Rcpp只需要使用大量的C ++粘合剂和模板魔法使API更好。

因此,除非你单独使用R来构建这些头文件,否则我看不出它如何用Rcpp构建。

答案 2 :(得分:0)

我也有这些错误。 599行错误花了我很长时间才解决。我注释掉了599行,并解决了下面的问题。

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

我不喜欢这个解决方案,但我的程序现在正在编译。这样做可能会有未来的问题,所以我记录了我的变化。谁有更好的解决方案?