使用第三方头文件与Rcpp [英] Using 3rd party header files with Rcpp

查看:294
本文介绍了使用第三方头文件与Rcpp的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个头文件 coolStuff.h ,包含一个函数 awesomeSauce(arg1)在我的cpp源文件中使用。



目录结构:




  • RworkingDirectory


    • sourceCpp


      • theCppFile.cpp


    • cppHeaders


      • coolStuff.h





代码:

  #include< Rcpp.h> 
#include< cppHeaders / coolStuff.h>
使用命名空间Rcpp;

// [[Rcpp :: export]]
double someFunctionCpp(double someInput){

double someOutput = awesomeSauce(someInput);

return someOutput;
}

我得到错误:

  theCppFile.cpp:2:31:error:cppHeaders / coolStuff.h:没有这样的文件或目录

我已经移动了文件和目录在所有的地方,似乎不能得到这个工作。我看到使用第三方标题的例子说,只是这样做:

  #include& boost / array。 hpp> 

(来自Hadley / devtools)



https://github.com/hadley/devtools/wiki/Rcpp



那么什么给了呢?



更新01.11.12


我已经在早上搜索,找不到对我来说似乎很简单的东西的答案。

好了,现在我已经想出了如何构建在Rstudio中使用Rcpp的包,让我重新整理这个问题。我有一个独立的头文件coolStuff.h,其中包含我想在我的cpp代码中使用的函数。



1)我应该在package目录结构中放置coolStuff.h,这样它包含的函数可以由CppFile.cpp使用?



2)如何在cpp文件中调用coolStuff.h?再次感谢您的帮助。我从最后的谈话中学到了很多。



注意:我阅读了写一个使用Rcpp的包的小插图,它不解释如何做到这一点。



答案:



好,让我总结我的问题的答案,因为它分散这一页。如果我得到一个细节错误,随时可以编辑或让我知道,我会编辑它:



所以你发现一个 .h 或 .cpp 文件,其中包含要在 .cpp中使用的函数或其他一些代码文件,您要使用 Rcpp



让我们继续调用这个找到的代码 coolStuff.h 并调用你想使用的函数 awesomeSauce()。让我们调用你正在编写的文件 theCppFile.cpp



文件和.cpp文件是所有的C ++代码,它们之间的区别是为C ++程序员保持正确的组织方式。我将离开讨论这里的差异,但在这里一个简单的搜索将导致你对于你的R程序员需要使用一个位o'代码,你发现,没有真正的区别。)



IN SHORT: 您可以使用像 coolStuff.h 这样的文件,前提是它不会调用其他库,只需剪切并粘贴到 theCppFile.cpp ,或者如果您创建了一个包,您可以将该文件放在 \src 目录中, theCppFile.cpp 文件,并在您正在编写的文件的顶部使用 #includecoolStuff.h。后者更灵活,允许您在其他 .cpp 文件中使用 coolStuff.h 中的函数。



详情:



1) coolStuff.h 不能调用其他库。这意味着它不能在顶部有任何include语句。如果是,我下面的细节可能不会工作,使用调用其他库的找到的代码超出了这个答案的范围。



2)如果你想要使用 sourceCpp()编译文件,您需要将 coolStuff.h 剪切并粘贴到 theCppFile.cpp 。我被告知有例外,但 sourceCpp()被设计为编译一个 .cpp 文件,路线采取。



(注意:我不保证一个简单的剪切和粘贴可以开箱即用,您可能需要重命名变量,或者更有可能切换数据类型过去与您在 theCppFile.cpp 中使用的那些一致。但是到目前为止,剪切和粘贴已经为我用6个简单 .h 文件)



3)如果你只需要使用 coolStuff.h theCppFile.cpp ,没有其他地方,那么你应该剪切并粘贴到 theCppFile.cpp



(再次我不能保证看到上面关于剪切和粘贴的注释)如果要使用 coolStuff.h 中包含的代码 theCppFile.cpp 和其他。 cpp 文件,您需要查看构建包。这不难,但可能有点棘手,因为有关使用Rcpp构建软件包的信息涵盖了从任何R软件包所需的详尽彻底的文档(但是这是在你的头上作为一个新手),以及新手敏感



这里是我的建议:



A)首先使用 coolStuff.h 的代码获取 theCppFile.cpp 剪切并粘贴到 theCppFile.cpp 中,它将与 sourceCpp()一起编译,并按预期工作。这不是必须的,但如果你是新的Rcpp或包,确保你的代码在这个简单的情况下,在你移动到下面更复杂的情况下工作是很好。



B)现在使用 Rcpp.package.skeleton()创建包,或者使用RStudio中的Build功能(强烈推荐)。您可以在 hadley中找到有关使用 Rcpp.package.skeleton()的详细信息/ devtools Rcpp属性晕影。有关使用Rcpp编写软件包的完整文档,请参阅编写使用Rcpp的软件包,但是这个假设你知道你的方式在C ++相当好,而不使用新的属性的方式做Rcpp。



如果使用RStudio或 compileAttributes(),请不要忘记Build& Reload在RStudio。



C)现在您应该在\R目录中看到一个名为 RcppExports.R 的文件。打开它,检查出来。在 RcppExports.R ,你应该看到你的 \src 中的所有.cpp文件的R包装函数,目录。非常甜。



D)尝试与在 theCppFile.cpp 中编写的函数对应的R函数。它工作吗?如果这样继续。



E)在构建你的软件包之后,你可以将 coolStuff.h 移动到 src



F)现在您可以删除剪切和粘贴代码从 theCppFile.cpp 和顶部的 theCppFile.cpp (和任何其他.cpp文件要使用coolStuff.h的代码) #includecoolStuff.h就在之后#include< Rcpp.h> 。注意,在ranker.h中没有括号,而是有。这是一个C ++约定,当包括由用户提供的本地文件而不是像Rcpp或STL等库文件...



G)现在你必须重建包。在RStudio这只是Build& Reload在生成菜单。如果你不使用RStudio,你应该运行 compileAttributes()



解决方案

问题是 sourceCpp 明确设计为仅构建单个独立源文件。如果你希望 sourceCpp 有依赖关系,那么它们需要是:


  1. p>在系统中包含目录(即 / usr / local / lib / usr / lib );或


  2. Rcpp :: depends 属性中列出的R程序包


正如Dirk所说,如果你想创建多个源文件,那么你应该考虑使用R包而不是 sourceCpp



请注意,如果您正在使用某个包,并对该包的src目录中的文件执行sourceCpp,则它会构建为,如同它在包中(即,您可以包括来自src目录或inst / include目录的文件)。


I have a header file called coolStuff.h that contains a function awesomeSauce(arg1) that I would like to use in my cpp source file.

Directory Structure:

  • RworkingDirectory
    • sourceCpp
      • theCppFile.cpp
    • cppHeaders
      • coolStuff.h

The Code:

#include <Rcpp.h>
#include <cppHeaders/coolStuff.h>
using namespace Rcpp;

// [[Rcpp::export]]
double someFunctionCpp(double someInput){

 double someOutput = awesomeSauce(someInput);

return someOutput;
}

I get the error:

 theCppFile.cpp:2:31: error: cppHeaders/coolStuff.h: No such file or directory

I have moved the file and directory all over the place and can't seem to get this to work. I see examples all over the place of using 3rd party headers that say just do this:

#include <boost/array.hpp>

(Thats from Hadley/devtools)

https://github.com/hadley/devtools/wiki/Rcpp

So what gives? I have been searching all morning and can't find an answer to what seems to me like a simple thing.

UPDATE 01.11.12

Ok now that I have figured out how to build packages that use Rcpp in Rstudio let me rephrase the question. I have a stand alone header file coolStuff.h that contains a function I want to use in my cpp code.

1) Where should I place coolStuff.h in the package directory structure so the function it contains can be used by theCppFile.cpp?

2) How do I call coolStuff.h in the cpp files? Thanks again for your help. I learned a lot from the last conversation.

Note: I read the vignette "Writing a package that uses Rcpp" and it does not explain how to do this.

The Answer:

Ok let me summarize the answer to my question since it is scattered across this page. If I get a detail wrong feel free to edit this or let me know and I will edit it:

So you found a .h or .cpp file that contains a function or some other bit of code you want to use in a .cpp file you are writing to use with Rcpp.

Lets keep calling this found code coolStuff.h and call the function you want to use awesomeSauce(). Lets call the file you are writing theCppFile.cpp.

(I should note here that the code in .h files and in .cpp files is all C++ code and the difference between them is for the C++ programer to keep things organized in the proper way. I will leave a discussion of the difference out here, but a simple search here on SO will lead you to discussion of the difference. For you the R programer needing to use a bit o' code you found, there is no real difference.)

IN SHORT: You can use a file like coolStuff.h provided it calls no other libraries, by either cut-and-pasteing into theCppFile.cpp, or if you create a package you can place the file in the \src directory with the theCppFile.cpp file and use #include "coolStuff.h" at the top of the file you are writing. The latter is more flexible and allows you to use functions in coolStuff.h in other .cpp files.

DETAILS:

1) coolStuff.h must not call other libraries. So that means it cannot have any include statements at the top. If it does, what I detail below probably will not work, and the use of found code that calls other libraries is beyond the scope of this answer.

2) If you want to compile the file with sourceCpp() you need to cut and paste coolStuff.h into theCppFile.cpp. I am told there are exceptions, but sourceCpp() is designed to compile one .cpp file, so thats the best route to take.

(NOTE: I make no guarantees that a simple cut and paste will work out of the box. You may have to rename variables, or more likely switch the data types being used to be consistent with those you are using in theCppFile.cpp. But so far, cut-and-paste has worked with minimal fuss for me with 6 different simple .h files)

3) If you only need to use code from coolStuff.h in theCppFile.cpp and nowhere else, then you should cut and paste it into theCppFile.cpp.

(Again I make no guarantees see the note above about cut-and-paste)

4) If you want to use code contained in coolStuff.h in theCppFile.cpp AND other .cpp files, you need to look into building a package. This is not hard, but can be a bit tricky, because the information out there about building packages with Rcpp ranges from the exhaustive thorough documentation you want with any R package (but that is above your head as a newbie), and the newbie sensitive introductions (that may leave out a detail you happen to need).

Here is what I suggest:

A) First get a version of theCppFile.cpp with the code from coolStuff.h cut-and-paste into theCppFile.cpp that compiles with sourceCpp() and works as you expect it to. This is not a must, but if you are new to Rcpp OR packages, it is nice to make sure your code works in this simple situation before you move to the more complicated case below.

B) Now build your package using Rcpp.package.skeleton() or use the Build functionality in RStudio (HIGHLY recommended). You can find details about using Rcpp.package.skeleton() in hadley/devtools or Rcpp Attributes Vignette. The full documentation for writing packages with Rcpp is in the Writing a package that uses Rcpp, however this one assumes you know your way around C++ fairly well, and does not use the new "Attributes" way of doing Rcpp.

Don't forget to "Build & Reload" if using RStudio or compileAttributes() if you are not in RStudio.

C) Now you should see in your \R directory a file called RcppExports.R. Open it and check it out. In RcppExports.R you should see the R wrapper functions for all the .cpp files you have in your \src directory. Pretty sweet.

D) Try out the R function that corresponds to the function you wrote in theCppFile.cpp. Does it work? If so move on.

E) With your package built you can move coolStuff.h into the src folder with theCppFile.cpp.

F) Now you can remove the cut-and-paste code from theCppFile.cpp and at the top of theCppFile.cpp (and any other .cpp file you want to use code from coolStuff.h) put #include "coolStuff.h" just after #include <Rcpp.h>. Note that there are no brackets around ranker.h, rather there are "". This is a C++ convention when including local files provided by the user rather than a library file like Rcpp or STL etc...

G) Now you have to rebuild the package. In RStudio this is just "Build & Reload" in the Build menu. If you are not using RStudio you should run compileAttributes()

H) Now try the R function again just as you did in step D), hopefully it works.

解决方案

The problem is that sourceCpp is expressly designed to build only a single standalone source file. If you want sourceCpp to have dependencies then they need to either be:

  1. In the system include directories (i.e. /usr/local/lib or /usr/lib); or

  2. In an R package which you list in an Rcpp::depends attribute

As Dirk said, if you want to build more than one source file then you should consider using an R package rather than sourceCpp.

Note that if you are working on a package and perform a sourceCpp on a file within the src directory of the package it will build it as if it's in the package (i.e. you can include files from the src directory or inst/include directory).

这篇关于使用第三方头文件与Rcpp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆