Estoy tratando de crear un objeto compartido que puedo cargar en R que llama a las funciones de Rust a través de la API C de R. Para llamar a Rust desde C, estoy siguiendo esta publicación de blog . Mi problema surge cuando intento crear la biblioteca compartida y vincularla a la biblioteca de Rust. El enlazador se queja de que no puede encontrar mi función Rust. Soy bastante nuevo en los lenguajes compilados y le he dedicado un par de días de esfuerzo antes de pasar a SO. En ese tiempo, he aprendido mucho sobre los indicadores del compilador y, sin embargo, no me acerco a una solución. Creo que puede ser algo obvio.
Mi código 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; } }agudos.h:
#include <stdint.h> int32_t treble(int32_t value);Mi código de óxido:
#![crate_type = "dylib"] #[no_mangle] pub extern fn treble(value: i32) -> i32 { value * 3 }Esto es lo que estoy haciendo en la línea de comando:
$ 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)Inspeccionando el archivo de objeto que crea el óxido:
$ nm -gU libglue.dylib ... 0000000000001750 T _trebleEn el código C++, debe declarar la función Rust (que está disponible a través de C ABI) como extern "C" .
triple.h
#include <stdint.h> extern "C" { int32_t treble(int32_t value); } El error que está recibiendo se debe a que el compilador de C ++ está alterando el nombre del método treble antes de intentar vincularlo. extern "C" desactiva la manipulación.
Además, su código Rust FFI siempre debe usar los tipos de la caja libc ; en su caso, quiere libc::int32_t .