我也为此苦苦挣扎了一段时间,但一旦你知道我实际上并不难。
首先按照以下说明创建一个 Rust 库:rust-inside-other-languages。
这是一个示例 Rust 库:
//src/lib.rs
#[no_mangle]
pub fn kelvin_to_fahrenheit(n: f64) -> f64 {
n * 9.0/5.0 - 459.67
}
如果您按照rust-inside-other-languages 中的说明进行操作,那么您应该能够生成*.so(或*.dll 或.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
最后在 Rstudo 中,写入这个文件:
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 中的-L 选项指向包含您的Rust 共享对象的目录。
- 还要注意
-l 选项是您的共享对象的名称,不带lib 前缀,也不带.so(或您系统上的任何东西)后缀。
- 在 R 中使用
Sys.setenv 设置LD_LIBRARY_PATH 变量不起作用。在启动 R 之前导出变量。
-
verbose 选项在那里,您可以看到 Rcpp 编译您的 C++ 文件所做的工作。请注意上面 PKG_LIBS 中的选项是如何用于编译 C++ 文件的。
-
rebuild 选项用于在您每次运行这行 R 代码时强制重建 C++ 文件。
如果一切顺利,则在交互式控制台中运行上面的 R 文件,当您到达最后一行时,它应该输出 80.33。
如果有什么不清楚的地方,请在 cmets 中提问,我会努力改进我的答案。
希望它有所帮助:)
最后一点,基本函数dyn.load 和.C 可以用作替代方法。但这需要编写比这种方法更多的样板包装代码。