c - 如何使用 Rcpp 创建依赖于共享库的 R 包?

标签 c r dll rcpp

我有一个从 C 源代码生成的共享库 libbcd.so。 我还有一些接口(interface)代码Rinterface.h, Rinterface.cpp,如下所示:

接口(interface).h:

#pragma once

#include <R.h>
#include <Rcpp.h>
extern "C" {
#include "bcd.h"
}

void call_bcd();

接口(interface).cpp

#include "Rinterface.h"

// [[Rcpp::export]]
void call_bcd() {
    mm_problem* pr = mm_problem_alloc();
    bcd_vars* vars = bcd_vars_alloc();
    bcd(pr, vars);
}

其中 mm_problem_alloc()、bcd_vars_alloc()、bcd(mm_problem*, bcd_vars*) 都是来自 libbcd.somm_problem 的函数和 bcd_vars 是来自 libbcd.so 的用户定义类型。

我用 Rcpp.package.skeleton("bcd") 创建了一个包,将 Rinterface 文件放在 src 文件夹下,如下所示Makevars

PKG_CPPFLAGS=-I/usr/local/lib/R/site-library/Rcpp/include/ -I/path/to/bcd/headers/
PKG_LIBS=-L/path/to/bcd/library/file -lbcd
  • 我可以用 R CMD SHLIB Rinterface.cpp 创建接口(interface)库
  • 我还可以使用 R CMD build 构建压缩包。

如果我在编译步骤后尝试使用 install.packages("/path/to/bcd_1.0.tar.gz", type = "source") 从源代码安装包,我尝试加载 libbcd.so 时出现错误:

** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘bcd’ in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/home/gomfy/R/x86_64-pc-linux-gnu-library/3.6/00LOCK-bcd/00new/bcd/libs/bcd.so':
  libbcd.so: cannot open shared object file: No such file or directory

基于 this post在我看来,解决方法是将 libbcd.so.c 源文件重命名为 .cpp,然后将它们放在src 文件夹。这是正确的吗?

一般来说,利用 Rcpp 能够从 R 调用第三方共享库的推荐方法是什么?我发现了一个相关问题 here但它没有涉及构建包的细节。我看过Writing R extensions vignette("Rcpp-introduction"), vignette("Rcpp-package") 但我不是无法得出明确的结论。所以,我很感激专家的帮助。谢谢!

最佳答案

简而言之,你不能。

系统级 共享库将由 ld.so 按需加载(在 Linux 上,在其他操作系统上类似,想法相同)。因此,如果您的包依赖于非标准或不常见的共享库,那就倒霉了。 这只有在 ld.so 知道它的情况下才能工作,而 R 包不能做到这一点。

可以做的是将您的libbcd 与您的包 的源代码捆绑在一起,并将它们构建为一个静态库 链接到您的包裹。那可行。更简单的方法可能只是将 libbcd 的源文件放入包 src/ 目录中——R 将处理其余部分。

关于c - 如何使用 Rcpp 创建依赖于共享库的 R 包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58808393/

相关文章:

r - FantasyRpartPlot 决策树中节点顶部的数字是什么意思?

r - 如何对工作区中的元素运行循环?

c# - 使用安全模式从 dll 中获取 char**(作为 (IntPtr) 参数传递给函数)

c - ASCII 到十进制值

c++ - 如何将 WebAssembly 编译成常规汇编/ native 代码(或 Cpp 等)?

.pc 文件 "PCC-S-02015, unable to open include file"和 "PCC-S-02201, Encountered the symbol "size_t""的编译错误

function - 查找Dll函数参数

c - 识别有效算术表达式以及识别有效标识符和运算符的 Lex 程序

r - 如何过滤具有相同列名的数据框?

C++/CLI 包装器 LNK2028 和 LNK2019 错误