当我从另一个.cpp文件调用cpp函数时出错

时间:2018-09-10 19:36:05

标签: c++ rcpp

我试图从另一个.cpp文件调用c ++函数。 我使用了.h标头。 看看下面我做了什么。

我有一个 f.h 文件:

#ifndef PACKAGENAME_ADD_H
#define PACKAGENAME_ADD_H

#include <Rcpp.h>
Rcpp::NumericVector f(Rcpp::NumericVector x) ;

#endif

f.cpp 文件:

#include <Rcpp.h>
using namespace Rcpp;

NumericVector f(NumericVector x) {
  return x * 2;
}

g.cpp 文件:

#include <Rcpp.h>
#include <f.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector g(NumericVector x) {
  return f(x);
}

这三个文件位于同一文件夹中,运行 g.cpp 时出现此错误:

Rcpp::sourceCpp('~/g.cpp')
  

dyn.load中的错误(“ /tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so”):     无法加载共享对象'/tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so':     /tmp/Rtmpdu4AWp/sourceCpp-x86_64-pc-linux-gnu-0.12.17/sourcecpp_260f5e1a9ebc/sourceCpp_9.so:未定义符号:_Z1fN4Rcpp6VectorILi14ENS_15PreserveStorageEEE

有人可以帮助我吗? 我正在使用ubuntu 18.04,并且具有R 3.4.4版本。

1 个答案:

答案 0 :(得分:3)

Rcpp上下文中,我最熟悉的处理方式是创建一个程序包。正如Ralf Stubner所指出的,在您发表在原始帖子中的情况下,这并不是必须的;将<>f.h的方括号(g.cpp)更改为引号("")后,您的代码可以用sourceCpp()编译为我很好:

Rcpp::sourceCpp("g.cpp")
g(1:10)
# [1]  2  4  6  8 10 12 14 16 18 20

(有关详细信息,请参见Rcpp Attributes vignette的1.10节)。

但是,如果最终需要编译多个.cpp文件(即,不仅依赖于另一个实现的文件),那么创建包的方法是。这听起来可能涉及或令人生畏,但是使用Rcpp提供的工具,确实非常简单。这是我将您的代码转换为软件包的步骤:

  1. 从R运行Rcpp::Rcpp.package.skeleton("SOanswer", example_code = FALSE)
  2. 删除文件Read-and-delte-me
  3. 将原始帖子中的C ++文件添加到src/文件夹中(只需进行一次较小的编辑-将<>f.h周围的方括号(g.cpp)更改为引号("")。
  4. 从R运行Rcpp::compileAttributes("SOanswer/")devtools::install("SOanswer/")

然后它应该可以很好地编译,您可以从R运行g()

SOanswer::g(1:10)
# [1]  2  4  6  8 10 12 14 16 18 20

我要说的是,要在第0步添加一个步骤:阅读https://cran.r-project.org/package=Rcpp上的小插曲,尤其是Rcpp Introduction和Rcpp Package的小插曲。您还可以检出this lovely example包中的coatless标头中由{{3}}提供的标头中的包。