共享库显然不包含任何例程
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.
果然没有深奥的魔法:
- 使用其他库中的头文件来声明标识符
- 编写一个简短的 C++ 文件来部署其中一个标识符
- Link 通过将
src/Makevars
中的 src/Makevars
添加到 PKG_LIBS
.
- 或者,如果您在包中隐藏了 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。
我正在尝试为 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.
果然没有深奥的魔法:
- 使用其他库中的头文件来声明标识符
- 编写一个简短的 C++ 文件来部署其中一个标识符
- Link 通过将
src/Makevars
中的src/Makevars
添加到PKG_LIBS
. - 或者,如果您在包中隐藏了 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。