2014-10-27 3 views
2

Это изначально казалось мне простой задачей, но я не могу заставить следующее работать. Я пытаюсь обернуть подпрограмму fortran в вызов Rcpp, чтобы использовать функцию в R для использования. Цель состоит в том, чтобы включить функцию в пакет, поэтому идея просто использовать dyn.load() в конкретном файле * .so не представляется возможным (если кто-то не покажет мне, как?). От чтения подобных сообщений я подозреваю, что указание флагов в файле makevars может решить проблему, но предоставленная информация очень красная here, и некоторые разъяснения будут искренне оценены.Обтекание функции fortran в Rcpp

Я сделал следующее как можно ближе к документации, как я мог бы следовать.

  1. Создать структуру пакета с Rcpp.package.skeleton
  2. Место мой FORtran файл (hello.f) в каталоге Src
  3. Created базовый файл CPP для обертки Rcpp (hello.cpp)
  4. Создать R-файл, чтобы создать вызов «чистую» функцию (т.е. избежать .Call для пользователя и позволяет запуск других внутренних вычисляет до .Call)

Однако, когда Я стараюсь строить свой пакет (с RStudio), я получаю следующее сообщение об ошибке выхода:

==> R CMD INSTALL --no-multiarch --with-keep.source fortran 

g++ -shared -o fortran.so RcppExports.o hello.o hello.o rcpp_hello_world.o -lgfortran -lm -lquadmath -L/usr/lib/R/lib -lR 
* installing to library ‘/home/.../R/x86_64-pc-linux-gnu-library/3.0’ 
* installing *source* package ‘fortran’ ... 
** libs 
hello.o: In function `hello_wrapper': 
/home/.../r_code/fortran/src/hello.cpp:16: multiple definition of `hello_wrapper' 
hello.o:/home/.../r_code/fortran/src/hello.cpp:16: first defined here 
collect2: error: ld returned 1 exit status 
make: *** [fortran.so] Error 1 
ERROR: compilation failed for package ‘fortran’ 
* removing ‘/home/.../R/x86_64-pc-linux-gnu-library/3.0/fortran’ 

Exited with status 1. 

Мои файлы следующим образом:

hello.f

subroutine hello() 
    print *, "hello world" 
end subroutine hello 

привет. h

extern "C" 
{ 
    void hello(); 
} 

hello.cpp

#include <R.h> 
#include <Rinternals.h> 
#include <Rdefines.h> 

#include "hello.h" 

#ifdef __cplusplus 
extern "C" 
{ 
    SEXP hello_wrapper(); 
} 
#endif 

SEXP 
hello_wrapper() 
{ 
    hello(); 
} 

wrapper.R

hello_r <- function(){ 
    .Call("hello_wrapper"); 
} 

ответ

1

Я считаю, что проблема такая же простая, как и R, когда вы включаете несколько файлов имени с разными расширениями. Попробуйте переименовать hello.f в hello_fortran.f и идите оттуда.

+0

Да, я тоже собирался это предложить. Кроме того, это должно быть тривиально. –

+0

Это меня ближе, переименовав 'hello.f' в' hello_fortran.f' и 'hello.cpp' на' hello_cpp.cpp', но теперь еще одна ошибка в 'dyn.load ... неспособная загрузить общий объект/home/.../fortran.so: undefined symbol: hello' – cdeterman

+1

@DirkEddelbuettel, я узнал, что функция fortran требует подчеркивания в заголовке и при вызове в файле cpp. После этого пакет успешно завершается. Я приму этот ответ, поскольку он решил мою первоначальную проблему, но спасибо, а также Дирк, я ценю вашу помощь. – cdeterman

1

Я думаю, что это может работать, если вы удалите

#ifdef __cplusplus 
extern "C" 
{ 
    SEXP hello_wrapper(); 
} 
#endif 

часть. Также посмотрите на виньетку Rcpp Attributes - вам не нужно писать wrapper.R вручную.

+0

Благодарим за отзыв, однако это не решило проблему. У меня все еще есть ошибка в отношении «множественного определения« hello_wrapper() ». Я также рассмотрю атрибуты Rcpp. – cdeterman

+0

Также вы знаете о '.Fortran()'? В этом вам не обязательно включать Rcpp. Но нужно ли/нужно выполнить некоторую работу на уровне C++, прежде чем звонить в Fortran? –

+0

Я знаю '.Fortran() ', но да, я хотел бы сделать некоторые C++ перед некоторыми вызовами Фортрана. Я видел это в других пакетах, которые я пытаюсь воспроизвести с помощью этой простой программы, но застрял в этой ошибке. – cdeterman

0

Функции Rcpp и .Fortran не могут одновременно существовать одновременно. Просто не включайте функции Fortran в src/RcppExports.cpp.

Смежные вопросы