【问题标题】:Function Declaration in user written Header/Namespace in Rcpp用户在 Rcpp 中编写的 Header/Namespace 中的函数声明
【发布时间】:2018-08-28 12:56:02
【问题描述】:

这个问题实际上是上一个问题Calling 'mypackage' function within public worker 的后续问题。而且我怀疑通过询问可以获得更深入的了解。

错误是

无法加载共享对象”在“ParallelExample.so”中

我想做的是在内部调用 R 包中的 Cpp 函数。为此,我编写了一个头文件并将其添加到 src 目录,并在此头文件中定义了一个命名空间。以下代码出现编译错误:

也就是说,我已经为这个问题找到了两种解决方案。

  1. 在头文件中定义函数而不是仅仅声明它。
  2. 将命名空间留在头文件之外。

从我对此主题所做的 cpp 研究来看,在 Rcpp 之外似乎可行且常见(在头文件的命名空间中声明函数)。这让我想知道这只是 mac 编译器的问题还是 Rcpp 的一个功能。

一、cpp文件:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

二、Cpp:

#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
#include <random>

using namespace RcppParallel;

struct PARALLEL_WORKER : public Worker{

  const arma::vec &input;
  arma::vec &output;

  PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}

  void operator()(std::size_t begin, std::size_t end){


    std::mt19937 engine(1);

    for( int k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

      output[k] = ExampleInternal::myfunc(index);
  }
}

};

// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){

  arma::vec input = arma::regspace(0, 500);
  arma::vec output(Len_in);

  PARALLEL_WORKER  parallel_woker(input, output);
  parallelFor( 0, Len_in, parallel_woker);
  return output;
}

最后是一个内部头文件,也在 src 目录中:

#ifndef EXAMPLEINTERNAL_H
#define EXAMPLEINTERNAL_H

#include <RcppArmadillo.h>
#include <Rcpp.h>

namespace ExampleInternal{

double myfunc(arma::vec vec_in);

}

#endif

【问题讨论】:

  • 无法加载 ParallelExample.so 听起来像是运行时链接问题,而不是设计问题。有这样的填充物吗?文件的目录是否在 LD_LIBRARY_PATH 上?
  • 这就是我命名的 R 包,所以它是由构建过程生成的。
  • 你真的可以看到共享库(.so)文件吗? .so 在 LD_LIBRARY_PATH 上?如果不是,则运行时链接器将看不到它。如果您有一个实际的可执行文件,请尝试“ldd”命令,它会给出一条关于缺少共享库的消息。
  • “.so”文件显示在“src”目录中

标签: c++ rcpp


【解决方案1】:

您声明并调用函数ExampleInternal::myfunc,然后在全局命名空间中定义函数myfunc。这不匹配,我很确定您未显示的其余错误消息表明在so 文件中找不到ExampleInternal::myfunc

解决方案:在定义函数时使用相同的命名空间:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
namespace ExampleInternal {

double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

}

我还删除了导出函数的注释。顺便说一句,不要同时包含 RcppAramdillo.hRcpp.h

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    相关资源
    最近更新 更多