"RcppArmadilloExtensions/sample.h" R 包构建步骤中的链接器错误

"RcppArmadilloExtensions/sample.h" Linker Error in R Package Build Step

我正在制作一个 R 包,它在某些源文件中使用了 Rcpp::RcppArmadillo::sample() 函数。特别是,我在 4 个不同的 cpp 文件中使用了该函数,并且在每个文件中我都添加了这一行 #include <RcppArmadilloExtensions/sample.h> 以包含所需的头文件。

一切正常,直到我想通过命令 R CMD build mypackage 构建包。我收到 duplicate symbol 错误,其中提到的头文件中定义的大多数函数都被列为重复符号。例如,ProbSampleNoReplaceFixProbSampleReplaceWalkerProbSampleReplace 等函数都被列为在这 4 个 cpp 文件之间重复。

我搜索了这个问题,解决方案是在 .cpp 文件而不是 .h 文件中定义变量或函数以防止重复,如果需要,请使用 extern在任何其他 cpp 文件中使用这些变量。但我认为该解决方案不适用于此处,因为头文件不是我编写的,我不想对位于 here.

sample.h 头文件进行任何更改

有什么解决这个问题的建议吗?预先感谢您的帮助。

根据德克的评论,这最终对我有用:

我删除了每个文件顶部多余的 headers 并将其放在一个地方。这可以通过两种方式完成。一种是放在一个访问函数中,可以在任何需要的地方调用。

另一种选择是,如果您的整个项目不是那么大,您可以将 header #include <RcppArmadilloExtensions/sample.h> 放在主 .cpp 文件之上,其中包含您的项目与多个职能。我实际上为我自己的项目做了后一种选择。

我能够使用@amir-nik 在他 2021 年 6 月 16 日的回答中陈述的第一个选项。

One is to put it in one access function that can be called anywhere needed.

由于我花了很长时间才弄清楚如何去做,所以我在这里提供了一个完整的示例,以防大家感兴趣。

首先,我制作了如下源文件sample.cpp。重载是因为我需要采样函数来处理两种不同的向量类型。

// [[Rcpp::depends(RcppArmadillo)]]

#include <RcppArmadilloExtensions/sample.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs){
  return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs){
  return Rcpp::RcppArmadillo::sample(x, size, replace, probs);
}

接下来,我制作了这个头文件sample.h

#ifndef SAMPLE_H
#define SAMPLE_H

#include <RcppArmadillo.h>
arma::vec sample(const arma::vec& x, const int& size, const bool& replace, const arma::vec& probs);
arma::uvec sample(const arma::uvec& x, const int& size, const bool& replace, const arma::vec& probs);
#endif

现在,通过编写 #include "sample.h",我可以在我的所有代码中使用 Rcpp::RcppArmadillo::sample()