Я хочу создать пакет R, который содержит код C ++, написанный кем-то другим. Это экспериментальная ветвь poppler, которая не была включена в основную версию poppler. Изменения касаются нескольких файлов c ++, по этой причине:
- Мне нужно создать пакет.
- Я не могу создать один файл. cpp с нужными функциями и связать Пакет R для локальной установки poppler, используя файл конфигурации, как, например, пакет Rtotools PDFtools (к сожалению).
У меня есть следующий код в cpp (вырезано для краткости) , а также все заголовочные файлы и cpp файлы из poppler, необходимые для компиляции кода внутри папки sr c.
#include <Rcpp.h>
//namespace Rcpp create class ambiguity
// using namespace Rcpp;
#include "glibc.h"
#include "config.h"
#include "poppler-document.h"
#include "poppler-global.h"
#include "poppler-page.h"
#include "poppler-page-transition.h"
#include "poppler-toc.h"
#include "poppler-font.h"
#include "poppler-image.h"
#include "poppler-embedded-file.h"
#include "poppler-page-renderer.h"
#include "poppler-rectangle.h"
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <ios>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include "poppler-version.h"
using namespace poppler;
(...)
// [[Rcpp::export]]
std::string fontR(std::string file_name) {
std::unique_ptr<poppler::document> doc(poppler::document::load_from_file(file_name));
//
// if (show_text_list) {
const int pages = doc->pages();
for (int i = 0; i < pages; ++i) {
Rcpp::Rcout << "Page " << (i + 1) << "/" << pages << ":" << std::endl;
std::unique_ptr<poppler::page> p(doc->create_page(i));
print_page_text_list(p.get());
}
return file_name;
}
Я запустил следующее для создания пакета:
sudo rm -r fontReadeR/
sudo Rscript -e 'Rcpp::Rcpp.package.skeleton("fontReadeR")'
sudo cp font_readR.cpp fontReadeR/src/ sudo cp cpp_files/*
fontReadeR/src/
cd fontReadeR/
sudo Rscript -e 'Rcpp::compileAttributes()'
sudo R CMD build .
R
И внутри RI запустил следующее:
devtools::install()
Компиляция кода, кажется, идет хорошо, но в конечном итоге я сталкиваюсь с ошибка неопределенного символа:
g++ -I/usr/share/R/include -DNDEBUG -I"/home/rollaet/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include" -fpic -g -O2 -fdebug-prefix-map=/build/r-base-AitvI6/r-base-3.4.4=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c rcpp_hello_world.cpp -o rcpp_hello_world.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o fontReadeR.so RcppExports.o font_readR.o poppler-document.o poppler-embedded-file.o poppler-font.o poppler-global.o poppler-image.o poppler-page-renderer.o poppler-page-transition.o poppler-page.o poppler-private.o poppler-rectangle.o poppler-toc.o poppler-version.o rcpp_hello_world.o -L/usr/lib/R/lib -lR
installing to /home/rollaet/R/x86_64-pc-linux-gnu-library/3.4/fontReadeR/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error: package or namespace load failed for ‘fontReadeR’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/home/rollaet/R/x86_64-pc-linux-gnu-library/3.4/fontReadeR/libs/fontReadeR.so':
/home/rollaet/R/x86_64-pc-linux-gnu-library/3.4/fontReadeR/libs/fontReadeR.so: undefined symbol: _ZTI10BaseStream
Error: loading failed
Execution halted
Я новичок в R cpp, и я повторил несколько ошибок новичка (начиная с использования R cpp :: source Cpp ()), и т. д. c, но я озадачен этой ошибкой и не вижу очевидного Я должен следовать, чтобы решить это. Он не пришел из определенной c части кода, так как я пытался прокомментировать другую часть кода, но безуспешно.
Я изучил структуру пакета Matrix и взглянул на nloptr ( это было немного сложно для меня) Должен ли я отказаться от этого подхода и go, чтобы создать библиотеку stati c с нужными мне файлами cpp?
Спасибо за вашу помощь.
Редактировать: Я думаю, что нашел В чем может быть проблема c часть, есть Перегрузка оператора <<, который ссылается на поток: </p>
static std::ostream& operator<<(std::ostream& stream, const poppler::ustring &str)
{
const poppler::byte_array ba = str.to_utf8();
for (unsigned int i = 0; i < ba.size(); ++i) {
stream << (char)(ba[i]);
}
return stream;
}