共享库显然不包含任何例程

shared library apparently not containing any routines

我正在尝试为 C++ library Faddeeva(各种类型的复杂错误函数)创建一个 R 接口;不幸的是,我在 R 中调用外部代码的经验很少,事实证明这是一个很大的挑战。

我天真的尝试,

R CMD SHLIB Faddeeva.cc

生成了一个共享库 Faddeeva.so,我将其加载到 R 中,

dyn.load("Faddeeva.so")
dlls <- getLoadedDLLs()
getDLLRegisteredRoutines(dlls[['Faddeeva']])

是空的,我还没有注册任何功能。我相信我必须编写一些接口代码来使用 SEXP,以便我可以使用 .Call 接口(Rcpp 可以使这一步更容易吗?),但我仍然对为什么这个共享库显示没有注册例程感到困惑.

非常欢迎任何关于开展此类项目的建议或指导!


编辑:感谢 Dirk 的回答和对 Rcpp 的帮助,接口现在在 Faddeeva package.

中实现

我会退后一步,看看其他使用外部库的包。老歌但金曲是 RcppGSL, but for example RcppRedis using the (C-library) hiredis.

果然没有深奥的魔法:

  1. 使用其他库中的头文件来声明标识符
  2. 编写一个简短的 C++ 文件来部署其中一个标识符
  3. Link 通过将 src/Makevars 中的 src/Makevars 添加到 PKG_LIBS.
  4. 或者,如果您在包中隐藏了 Johnson's Fadeeva 的源代码,只需包含 src/ 中的文件并跳过第 3 步。

请注意,我没有提及 Rcpp。它 "only" 有助于第 2 点。其余部分与将 C 库链接到 R 扩展相同。 CRAN 上可能有上千个不同的包。

如果你完全迷路了,先考虑the new list r-package-devel but do read a little in Writing R Extensions

杰尔默的包裹nloptr wraps another of Johnson's libraries: nlopt。也许这可以作为灵感。我帮助提高了安装效率(通过使用存在的系统 libnlopt)。

编辑: 我仔细查看了 page by Johnson。没有图书馆。只是一个 .cc.hh。将它们放入包的 src/ 中,可能重命名为 .cpp.h -- 你就完成了!

编辑 2: 好的,我根据刚才概述的食谱创建了一个小示例包。通过使用 Rcpp 调用者变得像

一样简单
#include <Rcpp.h>
using namespace Rcpp;

#include "Faddeeva.h"

// [[Rcpp::export]]
double Dawson(double x) { // special case for real x
  return Faddeeva::Dawson(x);
}

我们可以像往常一样使用这个包:

edd@max:/tmp$ Rscript -e 'library(RcppFaddeeva); Dawson(4.2)'
[1] 0.122761
edd@max:/tmp$ 

稍后我会把它放在 GitHub 上。

编辑 3: 现在是 in this GitHub repo