new_CppObject_xp неправильно сообщает об ошибке при передаче объекта Rcpp другому - PullRequest
0 голосов
/ 07 октября 2018

У меня есть два Rcpp-класса, A и B.Конструктор A извлекает некоторую информацию из своего параметра и выводит ее, чтобы доказать, что она работает.

B принимает объект A в качестве параметра конструктора и сообщает об ошибке, как если бы извлечение в конструкторе A завершилось неудачно.Но так как A распечатал извлеченные данные, это не могло завершиться ошибкой.

Как мне заставить B принять A в качестве параметра без ошибок?

MinimalВоспроизводимый пример:

library(Rcpp)

Rcpp::sourceCpp(code='
#include <Rcpp.h>

struct A {
  Rcpp::NumericVector y;

  A(Rcpp::List x)
    : y(Rcpp::as<Rcpp::NumericVector>(x["foo"]))
  {
    Rcpp::Rcout << y;
  }
};

struct B {
  B(A x) { }
};

RCPP_MODULE(A) {
  Rcpp::class_<A>("A")
  .constructor<Rcpp::List>();
}

RCPP_MODULE(B) {
  Rcpp::class_<B>("B")
  .constructor<A>();
}
')

Aobj <- new(A, list(foo=1:3))
Bobj <- new(B, Aobj)

Вывод:

> source('testcase.R', echo=TRUE)

> library(Rcpp)

> Rcpp::sourceCpp(code='
+ #include <Rcpp.h>
+ 
+ struct A {
+   Rcpp::NumericVector y;
+ 
+   A(Rcpp::List x)
+     : y(Rcpp::as<Rcpp::NumericVector> .... [TRUNCATED] 

> Aobj <- new(A, list(foo=1:3))
1 2 3
> Bobj <- new(B, Aobj)
Error in new_CppObject_xp(fields$.module, fields$.pointer, ...) : 
  Index out of bounds: [index='foo'].
> 

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

Я попытаюсь объяснить, почему ваше решение работает.С RCPP_MODULE(A) вы представляете структуру C ++ A как ссылочный класс в R. Это делается автоматически.Однако, когда вы вызываете Bobj <- new(B, Aobj), нет информации, как преобразовать этот ссылочный класс в требуемую структуру C ++.Используя RCPP_EXPOSED_CLASS(A), вы создаете специализацию Rcpp::wrap и Rcpp::as для преобразования между объектами C ++ и R обоими способами.Поскольку мы пропускаем только преобразование R в C ++, то есть Rcpp::as, нам также достаточно следующего:

#include <RcppCommon.h>
struct A;
RCPP_EXPOSED_AS(A)

#include <Rcpp.h>

struct A {
  Rcpp::NumericVector y;

  A(Rcpp::List x)
    : y(Rcpp::as<Rcpp::NumericVector>(x["foo"]))
  {
    Rcpp::Rcout << y;
  }
};

struct B {
  B(A x) { }
};

RCPP_MODULE(A) {
  Rcpp::class_<A>("A")
  .constructor<Rcpp::List>();
}

RCPP_MODULE(B) {
  Rcpp::class_<B>("B")
  .constructor<A>();
}

/*** R
Aobj <- new(A, list(foo=1:3))
Bobj <- new(B, Aobj)
*/
0 голосов
/ 07 октября 2018

Когда что-то не работает, хорошо (пере) прочитать некоторую документацию.В частности, Расширение Rcpp (PDF) , раздел 3.2.

В начале кода C ++ я добавил следующее:

#include <RcppCommon.h>
struct A;
RCPP_EXPOSED_CLASS(A);

… и теперь он работает нормально.,Я признаю, что не до конца понимаю, что здесь происходит, но это решение решает как MWE, так и мои оригинальные проблемы с кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...