Ошибка Rcpp при подключении внешней библиотеки?

Я бью головой о стену, пытаясь добратьсяRcppсобрать пакет для SPI на Raspberry Pi.

Мой код/пакет находится на моем GitHub:

Когда я бегуRcpp::compileAttributes()с последующимload_all()я постоянно получаю

RcppExports.cpp:14:32: ошибка: «spi_config_t» не объявлен

Итак, очевидно, что я не объявил и не связал что-то важное, но мне неясно, где мне нужно объявить ссылку и что мне нужно связать.

Был ли у кого-нибудь опыт работы с подобными вещами?

Начиная с исходного кода пакета, который можно найти по адресу https://github.com/mnr/rpigpior/https://github.com/mnr/rpigpior/ .

      > Rcpp::compileAttributes()
> load_all()

ℹ Loading rpigpior
Exports from /home/pi/Documents/rpigpior/src/rpi_spi_open.cpp:
   int rpi_spi_open(char *device, spi_config_t config)

/home/pi/Documents/rpigpior/src/RcppExports.cpp updated.
/home/pi/Documents/rpigpior/R/RcppExports.R updated.
ℹ Re-compiling rpigpior (debug build)
── R CMD INSTALL ───────────────────────────────────────────────────────────────────────────────────────────────────
─  installing *source* package ‘rpigpior’ ... (730ms)
   ** using staged installation
   ** libs
   using C compiler: ‘gcc (Raspbian 10.2.1-6+rpi1) 10.2.1 20210110’
   using C++ compiler: ‘g++ (Raspbian 10.2.1-6+rpi1) 10.2.1 20210110’
   g++ -std=gnu++17 -I"/opt/R/release/lib/R/include" -DNDEBUG  -I'/home/pi/R/armv7l-unknown-linux-gnueabihf-library/4.3/Rcpp/include' -I/usr/local/include    -fPIC  -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c RcppExports.cpp -o RcppExports.o
   RcppExports.cpp:14:32: error: ‘spi_config_t’ has not been declared
      14 | int rpi_spi_open(char *device, spi_config_t config);
         |                                ^~~~~~~~~~~~
   RcppExports.cpp: In function ‘SEXPREC* _rpigpior_rpi_spi_open(SEXPREC**, SEXP)’:
   RcppExports.cpp:19:57: error: cannot convert ‘SEXP’ {aka ‘SEXPREC*’} to ‘Rcpp::traits::input_parameter<char>::type*’ {aka ‘Rcpp::InputParameter<char>*’} in initialization
      19 |     Rcpp::traits::input_parameter< char >::type *device(*deviceSEXP);
         |                                                         ^~~~~~~~~~~
         |                                                         |
         |                                                         SEXP {aka SEXPREC*}
   In file included from /home/pi/R/armv7l-unknown-linux-gnueabihf-library/4.3/Rcpp/include/Rcpp/r/headers.h:67,
                    from /home/pi/R/armv7l-unknown-linux-gnueabihf-library/4.3/Rcpp/include/RcppCommon.h:30,
                    from /home/pi/R/armv7l-unknown-linux-gnueabihf-library/4.3/Rcpp/include/Rcpp.h:27,
                    from RcppExports.cpp:4:
   /opt/R/release/lib/R/include/Rinternals.h:180:16: note: class type ‘SEXPREC’ is incomplete
     180 | typedef struct SEXPREC *SEXP;
         |                ^~~~~~~
   RcppExports.cpp:20:36: error: ‘spi_config_t’ was not declared in this scope
      20 |     Rcpp::traits::input_parameter< spi_config_t >::type config(configSEXP);
         |                                    ^~~~~~~~~~~~
   RcppExports.cpp:20:49: error: template argument 1 is invalid
      20 |     Rcpp::traits::input_parameter< spi_config_t >::type config(configSEXP);
         |                                                 ^
   RcppExports.cpp:20:57: error: expected initializer before ‘config’
      20 |     Rcpp::traits::input_parameter< spi_config_t >::type config(configSEXP);
         |                                                         ^~~~~~
   RcppExports.cpp:21:56: error: ‘config’ was not declared in this scope
      21 |     rcpp_result_gen = Rcpp::wrap(rpi_spi_open(*device, config));
         |                                                        ^~~~~~
   make: *** [/opt/R/release/lib/R/etc/Makeconf:200: RcppExports.o] Error 1
   ERROR: compilation failed for package ‘rpigpior’
─  removing ‘/tmp/RtmpN8Haun/devtools_install_10981336a33c/rpigpior’
Error in `(function (command = NULL, args = character(), error_on_status = TRUE, …`:
! System command 'R' failed
---
Exit status: 1
stdout & stderr: <printed>
---

1 ответ

@coatless уже выявил одну ключевую проблему:Rcppне знает, поэтому вы не можете разместить его в интерфейсе, не выполняя при этом другой работы . Поскольку это структура, вам нужно проделать больше работы.

Я клонировал ваш репозиторий и после внесения этих изменений начал его сборку.

  1. Уменьшить/изменить интерфейс наint rpi_spi_open(std::string dev)как мы также предпочитаемstd::stringкchar *.

  2. Присвойте значение строкиconst char*:const char *device = dev.c_str();

  3. Объявитьspi_config_t. Функционально это нонсенс, но сначала мы хотим избавиться от компиляции.

  4. Исправьте ложный символ комментария#к//

  5. Пересоберите статическую библиотеку, вы включили ее в свой репозиторий git (плохая идея), которая в любом случае не подходит для моего x86_64. Скопируйте его под своим именем.

  6. Правильныйsrc/MakevarsиспользоватьPKG_LIBS = -L. -lspidev-lib++

Я думаю, что это все. Затем я могу собрать пакет, включающий этап компиляции:

      $ build.r      # convenience wrapper for R CMD build
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘rpigpior’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to build vignettes
* creating vignettes ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* re-saving image files
* building ‘rpigpior_0.1.0.tar.gz’

$ 

Итак, мы свели ваш очевидный Rcpp к логической проблеме, и теперь вам нужно понять, как заполнить структуру данных конфигурации из R. Другая проблема, и в основном ваша :)

PS Я отправил вам свои изменения в виде запроса на включение в ваш репозиторий .

Другие вопросы по тегам