useDynLib() 错误和 compileAttributes returns 无:将 C 库嵌入到 R 包中
useDynLib() error and compileAttributes returns nothing: embedding a C library into an R package
我有一个 C 包,它构建了一个带有多个参数标志的可执行文件。一个使用 Makefile 编译代码(我知道,这需要针对 R 包进行更改)并通过
创建一个可执行文件 运行
$ ./codeName -f path/inputfile -o path/outputfile -p ## -s "type"
我的目标是集成此 C 程序包中使用的几个函数以与 R 库一起使用。我看一下使用 C 的 R 包 github.com/cran
的一些示例。在编写 R 扩展中,它解释了我如何使用 .Call()
和 Makevars
从 R 调用 C 函数。我想避免像瘟疫一样。但是,看起来这需要使用 SEXP
对象进行大量重写——所以我求助于 Rcpp(是的!)
我创建包 Rcpp.package.skeleton("packageName")
太棒了。在 R 中,我执行以下操作:
$ R
> library(devtools)
> build() # works!
> install() # works!
> library(packageName)
> rcpp_hello_world()
## expected output
一切正常。然后我将我的 C 包添加到 /src
。然后,我通过 R 在包根目录中执行 Rcpp::compileAttributes()
——没有任何反应,也没有任何输出,这是预料之中的,因为我根本还没有更改 C 代码。
我尝试使用上面的命令安装:devtools::build()
和 devtools::install()
。通过 Makefile
,看起来 C 代码可以完美编译!但是还有这个问题:
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) :
shared object ‘packageName.so’ not found
Error: loading failed
Execution halted'
ERROR: loading failed
好吧,这有点令人困惑,我不知道为什么会这样,但问题是 NAMESPACE 中的 useDynLib("packageName")
。如果我删除它,C 代码似乎可以编译,并且通过上面的 build/install
命令安装包。 rcpp_hello_world()
仍然有效。
(1) 为什么现在会出现这个错误‘packageName.so’ not found
,我能绕过它吗?
(此题与Rcpp无关。)
然后,我转到 .c
文件。我加
#include <Rcpp.h>
using namespace Rcpp;
到 *.c
文件和 //[[Rcpp::export]]
我想导入的函数之前。 (我不确定这在 *.c
或 C 头文件中是否有效。)
接下来,我转到包根目录,打开 R 并尝试以下操作:
$ R
> library(Rcpp)
> compileAttributes()
运行没有错误。但是,没有生成 RcppExports.R
和 RcppExports.cpp
。编译C代码也会报找不到#include <Rcpp.h>
的错误。
(2) 为什么 compileAttributes()
在此环境中不起作用?我一定是错误地使用了 Rcpp
和 //[[Rcpp::export]]
以便将这些 C 函数包装成 R 可用的格式。
你会怎么称呼这个函数? C代码?
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
它作为 C 和 C++ 代码通过。所以我们称它为 C 代码。
您可以通过 Rcpp 与以下调用者清楚地从 R 接口:
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
将它们全部粘在一起到一个 C++ 文件中,这样 Rcpp 就可以对它们进行操作(见评论),你就完成了。
R> library(Rcpp)
R> sourceCpp("/tmp/ex.cpp")
R> callFib(10)
[1] 55
R>
完整文件如下。
#include <Rcpp.h>
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
/*** R
callFib(10)
*/
我有一个 C 包,它构建了一个带有多个参数标志的可执行文件。一个使用 Makefile 编译代码(我知道,这需要针对 R 包进行更改)并通过
创建一个可执行文件 运行$ ./codeName -f path/inputfile -o path/outputfile -p ## -s "type"
我的目标是集成此 C 程序包中使用的几个函数以与 R 库一起使用。我看一下使用 C 的 R 包 github.com/cran
的一些示例。在编写 R 扩展中,它解释了我如何使用 .Call()
和 Makevars
从 R 调用 C 函数。我想避免像瘟疫一样。但是,看起来这需要使用 SEXP
对象进行大量重写——所以我求助于 Rcpp(是的!)
我创建包 Rcpp.package.skeleton("packageName")
太棒了。在 R 中,我执行以下操作:
$ R
> library(devtools)
> build() # works!
> install() # works!
> library(packageName)
> rcpp_hello_world()
## expected output
一切正常。然后我将我的 C 包添加到 /src
。然后,我通过 R 在包根目录中执行 Rcpp::compileAttributes()
——没有任何反应,也没有任何输出,这是预料之中的,因为我根本还没有更改 C 代码。
我尝试使用上面的命令安装:devtools::build()
和 devtools::install()
。通过 Makefile
,看起来 C 代码可以完美编译!但是还有这个问题:
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) :
shared object ‘packageName.so’ not found
Error: loading failed
Execution halted'
ERROR: loading failed
好吧,这有点令人困惑,我不知道为什么会这样,但问题是 NAMESPACE 中的 useDynLib("packageName")
。如果我删除它,C 代码似乎可以编译,并且通过上面的 build/install
命令安装包。 rcpp_hello_world()
仍然有效。
(1) 为什么现在会出现这个错误‘packageName.so’ not found
,我能绕过它吗?
(此题与Rcpp无关。)
然后,我转到 .c
文件。我加
#include <Rcpp.h>
using namespace Rcpp;
到 *.c
文件和 //[[Rcpp::export]]
我想导入的函数之前。 (我不确定这在 *.c
或 C 头文件中是否有效。)
接下来,我转到包根目录,打开 R 并尝试以下操作:
$ R
> library(Rcpp)
> compileAttributes()
运行没有错误。但是,没有生成 RcppExports.R
和 RcppExports.cpp
。编译C代码也会报找不到#include <Rcpp.h>
的错误。
(2) 为什么 compileAttributes()
在此环境中不起作用?我一定是错误地使用了 Rcpp
和 //[[Rcpp::export]]
以便将这些 C 函数包装成 R 可用的格式。
你会怎么称呼这个函数? C代码?
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
它作为 C 和 C++ 代码通过。所以我们称它为 C 代码。
您可以通过 Rcpp 与以下调用者清楚地从 R 接口:
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
将它们全部粘在一起到一个 C++ 文件中,这样 Rcpp 就可以对它们进行操作(见评论),你就完成了。
R> library(Rcpp)
R> sourceCpp("/tmp/ex.cpp")
R> callFib(10)
[1] 55
R>
完整文件如下。
#include <Rcpp.h>
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
/*** R
callFib(10)
*/