2012-07-21 7 views
7

Próbuję napisać trochę kodu C++, który uzyskuje dostęp do niektórych rzeczy na poziomie systemu operacyjnego w systemie Windows, używając Rcpp. Gdy tylko dodam windows.h lub shlobj.h, otrzymuję pakiet błędów kompilacji. Kiedy uruchomię ten kod, to działa, więc wiem, że mam pewne podstawy w porządku. Ale kiedy odkomentuję jedną z linii związanych z Windows #include, to nie działa.Używanie Rcpp w specyficznych dla systemu Windows obejmuje

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() 

Uwaga: Gdy uruchomię to w RStudio, wyjście z cout i printf pojawiają się w konsoli, ale kiedy go uruchomić z Windows RGui, wyjście się nie pojawia. Zakładam, że ma to coś wspólnego ze sposobem, w jaki RGui obsługuje wyjście tekstowe.

Kiedy odkomentowaniu te obejmują linie błędy dostaję wyglądać następująco:

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] 

... i tak dalej

żadnych wskazówek, w jaki sposób dokonać tej pracy?


Aktualizacja: udało mi się niektóre błędy odejść, ale niektóre pozostają.

Mam również z Realloc błędów, wykonując kilka rad od http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1242.html

inc należy zastąpić:

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

ja też pozbył innych błędów przekazując -fpermissive do kompilatora, jak z tym pytanie: 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') 

Ale ar e jeszcze kilka błędów:

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 

Odpowiedz

5

Wymyśliłem ostatni problem. Wygląda na to, że zarówno nagłówki R, jak i Windows definiują Realloc i Free, ale istnieje pewien konflikt między definicjami. Tak więc potrzebowałem #undef obu tych makr przed dodaniem nagłówków Windows. I jest jeszcze kwestia przekazania flagi -fpermissive do kompilatora.

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() 
3

W pierwszym przybliżeniu można budować tylko z RCPP czy można zbudować z samą R jak RCPP właśnie sprawia, że ​​API ładniejszy z dużą ilością kleju i C++ szablonu magii.

Więc jeśli nie otrzymasz tych nagłówków do zbudowania w programie z samym R, nie widzę, jak mógł on budować z Rcpp.

+1

Dzięki, masz rację - to wygląda na ogólny problem z nagłówkami R i Windows. – wch

0

Mam również te błędy. A błąd linii 599 zabrał mi dużo czasu na naprawę. Skomentowałem linię 599 i naprawiłem problem poniżej.

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 

nie podoba mi się to rozwiązanie, ale mój program kompiluje teraz. Mogą to być przyszłe problemy, więc udokumentowałem moją zmianę. Ktoś ma lepsze rozwiązanie?

Powiązane problemy