Как сделать встроенные вызовы функций C ++ в R? - PullRequest
4 голосов
/ 21 октября 2011

Хорошо, так что я программирую на R и хочу создать функцию C ++. Я импортировал Rcpp и встроенные библиотеки. Сейчас я просто пытаюсь сделать простую функцию, которая добавляет 2 числа, но независимо от того, что я пытаюсь, я получаю ошибки.

Вот мой код:

cppstring = 'double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();'
hi <- cfunction(body=cppstring, signature(s="double"), Rcpp = TRUE)

и когда я вхожу во вторую строку, я получаю

file628a34ce.cpp: In function ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1

ERROR(s) during compilation: source code errors or compiler configuration errors!

Program source:
1: #include <Rcpp.h>
2: 
3: 
4: extern "C" {
5:   SEXP file628a34ce ( SEXP s );
6: }
7: 
8: SEXP file628a34ce ( SEXP s ) {
9: double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();
10:   Rf_warning("your C program does not return anything!");
11:   return R_NilValue;
12: }
Error in compileCode(f, code, language, verbose) : 
Compilation ERROR, function(s)/method(s) not created! file628a34ce.cpp: In function    ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1

Я перепробовал все, что только мог придумать, от приведения до перемещения кода, до #include RcppSexp, до простого возврата s, и каждый раз, когда я получаю какую-то ошибку, будь то

cannot convert ‘double’ to ‘SEXPREC*’ in return

или

invalid use of undefined type ‘struct SEXPREC’

или

forward declaration of ‘struct SEXPREC’

... Я так запутался :( Я посмотрел несколько примеров в Интернете, и то, что у меня сейчас есть, похоже, то, что делают все остальные, и это волшебным образом работает для них ...

Что это за SEXPREC *, что я постоянно вижу повсюду? И что это за внешняя функция "C", которую она делает? И почему он генерирует операторы ПОСЛЕ моего оператора return и сообщает, что моя функция ничего не возвращает, даже если это так?

1 Ответ

8 голосов
/ 21 октября 2011

Есть ли причина, по которой вы не начинаете (буквально !!) десятки примеров Rcpp, использующих inline?

Кроме того, что же такое RcppSexp? Какая документация у вас следующая?

Вот пример, который я сделал вчера вечером для кого-то на rcpp-devel (к которому вы, вероятно, должны присоединиться):

library(Rcpp)
library(inline)

xorig <- c(1, -2, 3, -4, 5, -6, 7)

code <- '
    Rcpp::NumericVector x(xs);
    Rcpp::NumericVector xa = sapply( x, ::fabs );
    return(xa);
    '

xabs <- cxxfunction(signature(xs="numeric"),
                    plugin="Rcpp",
                    body=code)

xabs(xorig)

Это более сложный пример, поскольку он использует Rcpp sugar , чтобы дать нам векторизованное выражение a R в C ++, которое мы продемонстрируем здесь с помощью простого sapply() из Rcpp сахар :

R> library(Rcpp)
R> library(inline)
R> 
R> xorig <- c(1, -2, 3, -4, 5, -6, 7)
R> 
R> code <- '
+     Rcpp::NumericVector x(xs);
+     Rcpp::NumericVector xa = sapply( x, ::fabs );
+     return(xa);
+     '
R> 
R> xabs <- cxxfunction(signature(xs="numeric"),
+                     plugin="Rcpp",
+                     body=code)
R> 
R> xabs(xorig)
[1] 1 2 3 4 5 6 7
R> 

Это наиболее наглядно демонстрирует два ваших запроса: мы используем неявные преобразователи шаблонов as<>(), чтобы перейти от SEXP, заданного от R, к начальному вектору, а затем используем неявный преобразователь шаблонов wrap() для возврата преобразованного второго вектора.

Все это подробно объясняется в виньетке Rcpp-введения и других виньетках в документации Rcpp.

...