2017-03-19 5 views
0

Ich schreibe einige C++ - Komponenten für meine R-Paket mit RcppEigen und ich habe Probleme mit Typdefs in diesem Zusammenhang. Der folgende Code wird nicht kompiliert:Kompilierungsfehler mit Rcpp mit typedef

// [[Rcpp::depends(RcppEigen)]] 
#include <RcppEigen.h> 

using namespace Rcpp; 

typedef Eigen::ArrayXd MapAr1; 

// [[Rcpp::export]] 
MapAr1 myFun(const MapAr1& x){ 

    MapAr1 y = x; 
    y[0] = 0; 

    return y; 

} 

Hier ist der Fehler:

==> Rcpp::compileAttributes() 

* Updated src/RcppExports.cpp 
* Updated R/RcppExports.R 

==> devtools::document(roclets=c('rd', 'collate', 'namespace')) 

Updating my_package documentation 
Loading my_package 
Re-compiling my_package 
'/usr/lib64/R/bin/R' --no-site-file --no-environ --no-save --no-restore \ 
    --quiet CMD INSTALL '/my_path/my_package' \ 
    --library='/tmp/RtmpgPjAdf/devtools_install_125071da0b53' --no-R --no-data \ 
    --no-help --no-demo --no-inst --no-docs --no-exec --no-multiarch \ 
    --no-test-load 

* installing *source* package ‘my_package’ ... 
g++ -m64 -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/my_path/R/x86_64-redhat-linux-gnu-library/3.3/Rcpp/include" -I" /my_path/R/x86_64-redhat-linux-gnu-library/3.3/RcppEigen/include" -fpic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -c RcppExports.cpp -o RcppExports.o 
** libs 
RcppExports.cpp:10:1: error: ‘MapAr1’ does not name a type 
MapAr1 myFun(const MapAr1& x); 
^ 
RcppExports.cpp: In function ‘SEXPREC* my_package_myFun(SEXP)’: 
RcppExports.cpp:15:42: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive] 
    Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP); 
             ^
RcppExports.cpp:15:50: error: template argument 1 is invalid 
    Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP); 
               ^
RcppExports.cpp:15:58: error: expected initializer before ‘x’ 
    Rcpp::traits::input_parameter< const MapAr1& >::type x(xSEXP); 
                 ^
RcppExports.cpp:16:40: error: ‘x’ was not declared in this scope 
    rcpp_result_gen = Rcpp::wrap(myFun(x)); 
             ^
RcppExports.cpp:16:41: error: ‘myFun’ was not declared in this scope 
    rcpp_result_gen = Rcpp::wrap(myFun(x)); 
             ^
make: *** [RcppExports.o] Error 1 
ERROR: compilation failed for package ‘my_package’ 
* removing ‘/tmp/RtmpgPjAdf/devtools_install_125071da0b53/my_package’ 
Error: Command failed (1) 
Execution halted 

Exited with status 1. 

Der gleiche Code außerhalb des Pakets kompiliert. Ich vermute also, dass etwas nicht korrekt in die RcppExports-Dateien kopiert wurde. Ich habe auch ein ähnliches Problem festgestellt, als ich versuchte, den Namespace RcppEigen zu verwenden: using namespace RcppEigen; wird nicht kopiert.

Irgendeine Idee, wie man das löst, ohne RcppExports von Hand zu ändern? Danke!

Antwort

6

Sie machen Ihr Leben zu kompliziert, indem Sie auf der typedef bestehen. Sobald Sie es in die Datei und Ihre Funktion Signatur aufnehmen, wird es Teil der Schnittstelle und muss daher auch in Ihrem RcppExports.cpp sein. Sie müssen es also "eine Stufe höher" anbieten.

Aber es gibt eine Bestimmung dafür: Rufen Sie die Datei pkgname_types.h und es wird enthalten sein. Ich habe ein einfaches Paket eigentest und eine Datei eigentest_types.h im src/ Verzeichnis hinzugefügt:

#include <RcppEigen.h> 

typedef Eigen::ArrayXd MapAr1; 

und hinzugefügt, um es dann zu Ihrem Code-Schnipsel mit

#include "eigentest_types.h" 

anstelle der typedef.

Das ist alles was Sie brauchen - ersetzen Sie einfach eigentest durch Ihren Paketnamen.

+0

Vielen Dank! Das funktioniert jetzt tatsächlich. Gut zu wissen ... – ixpl