创建链接到Rust dylib的共享C对象以在R中使用

我正在尝试创建一个可以加载到R中的共享对象,它通过R的C API调用Rust函数。 要从C调用Rust,我正在关注此博文 。 当我尝试创建共享库并链接到Rust库时,我的问题出现了。 链接器抱怨它无法找到我的Rust函数。 我对编译语言很陌生,在转向SO之前已经花了几天的努力。 在那段时间里,我学到了很多关于编译器标志的知识,但却没有更接近解决方案。 我认为这可能是显而易见的事情。

我的C ++代码:

#include "Rinternals.h" #include "Rh" #include "treble.h" // test.cpp extern "C" { SEXP triple(SEXP val) { int32_t ival = *INTEGER(val); Rprintf("9 tripled is %d\n", treble(ival)); return R_NilValue; } } 

treble.h:

 #include  int32_t treble(int32_t value); 

我的Rust代码:

 #![crate_type = "dylib"] #[no_mangle] pub extern fn treble(value: i32) -> i32 { value * 3 } 

这就是我在命令行上所做的事情:

 $ rustc glue.rs $ g++ -shared test.cpp -o test.so -I/Library/Frameworks/R.framework/Headers -L/Library/Frameworks/R.framework/Libraries -L. -lR -lglue Undefined symbols for architecture x86_64: "treble(int)", referenced from: _triple in test-dac64b.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) 

检查生锈的目标文件:

 $ nm -gU libglue.dylib ... 0000000000001750 T _treble 

在C ++代码中,您需要将Rust函数(可通过C ABI获得)声明为extern "C"

treble.h

 #include  extern "C" { int32_t treble(int32_t value); } 

您得到的错误是因为C ++编译器在尝试链接它之前将该方法称为 trebleextern "C"禁用了重复。

此外,您的Rust FFI代码应始终使用libc crate中的类型; 在你的情况下,你想要libc::int32_t