9

我正在尝试使用 Rcpp 编写一些 C++ 代码来访问 Windows 中的一些操作系统级别的东西。一旦我包含windows.hor 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()

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

... 等等

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


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

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

我还通过传递-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
4

3 回答 3

5

我发现了最后一个问题。看起来 R 和 Windows 标头都定义了Reallocand Free,但定义之间存在一些冲突。因此,在包含 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()
于 2012-07-21T16:33:09.657 回答
3

在第一个近似值上,如果您可以使用 R 本身构建,您只能使用 Rcpp 构建,因为 Rcpp 只是通过大量 C++ 胶水和模板魔法使 API 变得更好。

所以除非你让这些头文件单独用 R 构建一个程序,否则我看不出它如何用 Rcpp 构建。

于 2012-07-21T03:41:31.783 回答
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

我不喜欢这个解决方案,但我的程序现在正在编译。这样做可能会在未来出现问题,因此我记录了我的更改。有人有更好的解决方案吗?

于 2012-12-08T03:26:59.170 回答