Во-первых, возможно ли это сделать?Можно ли вызывать скрипты C и C ++, которые находятся в одном и том же пакете R?
Да. Rcpp очень широко использует API R C .(cf Раздел 1.6.4 Переносимый код C и C ++ из Запись расширений R .
Если возможно предыдущее, как тогда правильно зарегистрироватьфункции в сценариях C и C ++.
В идеале, только поверхностные аспекты из сценария C ++ . В противном случае вы застряли при написании клея.
IЯ использовал этот подход. В посте подробно описываются небольшие изменения. Рабочий пример можно найти за пределами сайта по адресу:
https://github.com/r-pkg-examples/rcpp-and-c
Короче, мы "создадим заголовочный файл для определений функций и включим его в код C . Оттуда мы создадим третий файл в C ++ и экспортируем эту функцию в R с использованием _Rcpp.
convolve_in_c.h
Здесь мы используем защиту включения через #ifndef
и #define
, чтобы гарантировать, что определения функций не повторяются, если мы повторно используем заголовокфайл несколько раз.
#ifndef CONVOLVE_C_H
#define CONVOLVE_C_H
SEXP convolve_c(SEXP a, SEXP b);
#endif /* CONVOLVE_C_H */
convolve_in_c.c
Теперь давайте изменим файлчтобы разрешить использование нашего пользовательского заголовка.
#include <R.h>
#include <Rinternals.h>
// Incorporate our header
#include "convolve_in_c.h"
SEXP convolve_c(SEXP a, SEXP b) {
int na, nb, nab;
double *xa, *xb, *xab;
SEXP ab;
a = PROTECT(coerceVector(a, REALSXP));
b = PROTECT(coerceVector(b, REALSXP));
na = length(a); nb = length(b);
nab = na + nb - 1;
ab = PROTECT(allocVector(REALSXP, nab));
xa = REAL(a); xb = REAL(b); xab = REAL(ab);
for(int i = 0; i < nab; i++)
xab[i] = 0.0;
for(int i = 0; i < na; i++)
for(int j = 0; j < nb; j++)
xab[i + j] += xa[i] * xb[j];
UNPROTECT(3);
return ab;
}
convolve_from_c_to_rcpp.cpp
Наконец, мы включаем код C , используя extern
в нашем C ++ *Файл 1057 *, в котором имя функции в C ++ совпадает со связью C .Кроме того, мы манипулируем типом данных от SEXP
до NumericVector
.
#include "Rcpp.h"
// Define the method signature
#ifdef __cplusplus
extern "C" {
#endif
#include "convolve_in_c.h"
#ifdef __cplusplus
}
#endif
//' Call C function from Rcpp
//'
//' Uses the convolve_c function inside of a C++ routine by Rcpp.
//'
//' @param a,b A `numeric` vector.
//'
//' @return
//' A `numeric` vector of length \eqn{N_a + N_b}.
//'
//' @examples
//'
//' convolve_from_c(1:5, 5:1)
//'
//' @export
// [[Rcpp::export]]
Rcpp::NumericVector convolve_from_c(const Rcpp::NumericVector& a,
const Rcpp::NumericVector& b) {
// Compute the result in _C_ from _C++_.
SEXP ab = convolve_c(a, b);
// Cast as an _Rcpp_ NumericVector
Rcpp::NumericVector result( ab );
// Alternatively:
// Rcpp::NumericVector result( convolve_c(a, b) );
// Return result
return result;
}