我也为此苦苦挣扎了一段时间,但一旦你知道了它实际上并不那么困难。
首先按照以下说明创建 Rust 库:其他语言中的 rust https://doc.rust-lang.org/stable/book/rust-inside-other-languages.html。
这是一个 Rust 库示例:
//src/lib.rs
#[no_mangle]
pub fn kelvin_to_fahrenheit(n: f64) -> f64 {
n * 9.0/5.0 - 459.67
}
如果您按照中的说明进行操作其他语言中的 rust https://doc.rust-lang.org/stable/book/rust-inside-other-languages.html,那么你应该能够生成一个*.so
(or *.dll
or .dylib
,取决于您的系统)。我们假设这个编译后的文件名为libtempr.so
.
现在创建一个 C++ 文件,它将把您需要的函数传递给 R:
//embed.cpp
extern "C" {
double kelvin_to_fahrenheit(double);
}
// [[Rcpp::export]]
double cpp_kelvin_to_fahrenheit(double k) {
double f = kelvin_to_fahrenheit(k);
return(f);
}
现在,在启动 R 之前,请确保环境变量LD_LIBRARY_PATH
包含先前生成的共享对象的目录(libtempr.so
) 被储存了。在外壳中执行以下操作:
$ export LD_LIBRARY_PATH=/home/sam/path/to/shared/object:$LD_LIBRARY_PATH
$ rstudio # I highly recommend using Rstudio for your R coding
最后在Rstudio中写入这个文件:
library(Rcpp)
Sys.setenv("PKG_LIBS"="-L/home/sam/path/to/shared/object -ltempr")
sourceCpp("/home/sam/path/to/embed.cpp", verbose = T, rebuild = T)
cpp_kelvin_to_fahrenheit(300)
- 请注意,在
Sys.setenv
the -L
选项指向包含 Rust 共享对象的目录。
- 还要注意的是
-l
选项是您的共享对象的名称,不带lib
前缀并且没有.so
(或者你系统上的任何东西)postfix。
- Using
Sys.setenv
在 R 中设置LD_LIBRARY_PATH
多变的不起作用。在启动 R 之前导出变量。
- The
verbose
那里有选项,这样你就可以看到什么Rcpp
编译你的C++文件。注意其中的选项PKG_LIBS
以上用于编译 C++ 文件。
- The
rebuild
options 可以在每次运行这行 R 代码时强制重建 C++ 文件。
如果一切顺利,然后在交互式控制台中运行上面的 R 文件,它应该输出80.33
当你到达最后一行时。
如果有任何不清楚的地方,请在评论中提问,我会尽力改进我的答案。
希望它有帮助:)
最后一点,基本功能dyn.load
and .C
可以用作替代方法。但这需要编写比这种方法更多的样板包装代码。