У меня есть файл заголовка coolStuff.h
, который содержит функцию awesomeSauce(arg1)
, которую я хотел бы использовать в исходном файле cpp.
Структура каталогов:
- RworkingDirectory
- sourceCpp
- theCppFile.cpp
- cppHeaders
- coolStuff.h
- sourceCpp
Код:
#include <Rcpp.h>
#include <cppHeaders/coolStuff.h>
using namespace Rcpp;
// [[Rcpp::export]]
double someFunctionCpp(double someInput){
double someOutput = awesomeSauce(someInput);
return someOutput;
}
Я получаю сообщение об ошибке:
theCppFile.cpp:2:31: error: cppHeaders/coolStuff.h: No such file or directory
Я переместил файл и каталог повсюду и не могу заставить это работать. Я вижу примеры повсюду в использовании сторонних заголовков, которые говорят, просто сделайте это:
#include <boost/array.hpp>
(Thats from Hadley/devtools)
https://github.com/hadley/devtools/wiki/Rcpp
Итак, что дает? Я искал все утро и не могу найти ответ на то, что мне кажется простым.
ОБНОВЛЕНИЕ 01.11.12
Теперь, когда я понял, как создавать пакеты, которые используют Rcpp в Rstudio, позвольте мне перефразировать вопрос. У меня есть отдельный файл заголовка coolStuff.h, который содержит функцию, которую я хочу использовать в моем коде cpp.
1) Где я должен помещать coolStuff.h в структуру каталога пакета, чтобы содержащаяся в нем функция могла использоваться CppFile.cpp?
2) Как я могу назвать coolStuff.h в файлах cpp? В очередной раз благодарим за помощь. Я многое узнал из последнего разговора.
Примечание. Я прочитал виньетку "Написание пакета, который использует Rcpp", и он не объясняет, как это сделать.
Ответ:
Хорошо, давайте подытожим ответ на мой вопрос, поскольку он разбросан по этой странице. Если я получу деталь неправильно, не стесняйтесь редактировать это или дайте мне знать, и я отредактирую его:
Итак, вы нашли файл .h
или .cpp
, содержащий функцию или другой бит кода, который вы хотите использовать в файле .cpp
, который вы пишете, для использования с Rcpp
.
Позволяет продолжать вызов этого найденного кода coolStuff.h
и вызывать функцию, которую вы хотите использовать awesomeSauce()
. Позволяет вызвать файл, который вы пишете theCppFile.cpp
.
(Здесь я должен отметить, что код в файлах .h и в .cpp файлах - это все код на С++, и разница между ними заключается в том, что программист на С++ должен правильно организовывать вещи. Я оставлю обсуждение Разница здесь, но простой поиск здесь на SO приведет вас к обсуждению разницы. Для вас, программист R, которому нужно использовать немного кода, который вы нашли, нет никакой реальной разницы.)
В КОРОТКЕ: Вы можете использовать такой файл, как coolStuff.h
, если он не вызывает никаких других библиотек, либо вырезать и вставить в theCppFile.cpp
, либо если вы создадите пакет, файл в каталоге \src
с файлом theCppFile.cpp
и используйте #include "coolStuff.h"
в верхней части файла, который вы пишете. Последний более гибкий и позволяет использовать функции в coolStuff.h
в других файлах .cpp
.
ПОДРОБНОСТИ:
1) coolStuff.h
не должен вызывать другие библиотеки. Таким образом, это означает, что у него не может быть никаких операторов включения вверху. Если это так, то, что я подробно ниже, вероятно, не будет работать, и использование найденного кода, вызывающего другие библиотеки, выходит за рамки этого ответа.
2) Если вы хотите скомпилировать файл с помощью sourceCpp()
, вам нужно вырезать и вставить coolStuff.h
в theCppFile.cpp
. Мне сказали, что есть исключения, но sourceCpp()
предназначен для компиляции одного файла .cpp
, так что это лучший маршрут для принятия.
(ПРИМЕЧАНИЕ. Я не гарантирую, что простой вырез и вставка будут работать из коробки. Возможно, вам придется переименовывать переменные или, скорее всего, переключать используемые типы данных, чтобы они соответствовали тем, которые вы используете в theCppFile.cpp
Но до сих пор cut-and-paste работала с минимальной суетой для меня с 6 различными простыми файлами .h
)
3) Если вам нужно всего лишь использовать код из coolStuff.h
в theCppFile.cpp
и нигде больше, вы должны вырезать его и вставить в theCppFile.cpp
.
(Снова я не делаю никаких гарантий, см. примечание выше о вырезании и вставке)
4) Если вы хотите использовать код, содержащийся в coolStuff.h
в theCppFile.cpp
И других файлах .cpp
, вам нужно посмотреть на создание пакета. Это не сложно, но может быть немного сложнее, потому что информация о создании пакетов с Rcpp варьируется от исчерпывающей полной документации, которую вы хотите с любым пакетом R (но это выше вашей головы как новичок), и новичок, чувствительный (которые могут не учитывать детали, которые вам понадобятся).
Вот что я предлагаю:
A) Сначала получите версию theCppFile.cpp
с кодом coolStuff.h
cut-and-paste в theCppFile.cpp
, который скомпилируется с sourceCpp()
и работает так, как вы ожидаете. Это не обязательно, но если вы новичок в Rcpp OR-пакетах, приятно убедиться, что ваш код работает в этой простой ситуации, прежде чем переходить к более сложному случаю ниже.
B) Теперь создайте свой пакет с помощью Rcpp.package.skeleton()
или используйте функциональные возможности Build в RStudio (настоятельно рекомендуется). Вы можете найти информацию об использовании Rcpp.package.skeleton()
в hadley/devtools или Атрибуты Rcpp Виньетка. Полная документация для написания пакетов с Rcpp находится в Написание пакета, который использует Rcpp, однако это предполагает, что вы хорошо знаете свой путь вокруг С++, и не использует новый способ "Атрибуты" для выполнения Rcpp.
Не забудьте "Сборка и перезагрузка", если вы используете RStudio или compileAttributes()
, если вы не находитесь в RStudio.
C) Теперь вы должны увидеть в своем каталоге \R файл с именем RcppExports.R
. Откройте его и проверьте. В RcppExports.R
вы должны увидеть функции обертки R для всех файлов .cpp, которые у вас есть в каталоге \src
. Довольно сладкий.
D) Попробуйте выполнить функцию R, соответствующую функции, которую вы написали в theCppFile.cpp
. Это работает? Если так двигаться дальше.
E) С помощью встроенного пакета вы можете перемещать coolStuff.h
в папку src
с помощью theCppFile.cpp
.
F) Теперь вы можете удалить код вырезания и вставки из theCppFile.cpp
и вверху theCppFile.cpp
(и любой другой .cpp файл, который вы хотите использовать для кода из coolStuff.h), поместите #include "coolStuff.h"
только после #include <Rcpp.h>
. Обратите внимание, что нет скобок вокруг ranker.h, а есть "". Это соглашение на С++ при включении локальных файлов, предоставляемых пользователем, а не в библиотечный файл, такой как Rcpp или STL и т.д.
G) Теперь вам нужно перестроить пакет. В RStudio это просто "Build and Reload" в меню "Построение". Если вы не используете RStudio, вы должны запустить compileAttributes()
H) Теперь попробуйте R-функцию снова так же, как вы сделали на шаге D), надеюсь, это сработает.