Я пытаюсь создать общий объект, который я могу загрузить в R, который вызывает функции Rust с помощью R API C. Чтобы позвонить Rust из C, я слежу за этим Сообщение блога. Моя проблема возникает, когда я пытаюсь создать общую библиотеку и создать ссылку на библиотеку Rust. Компоновщик жалуется, что не может найти мою функцию Rust. Я довольно плохо знаком с скомпилированными языками и потратил на это пару дней усилий, прежде чем обратиться к SO. За это время я многое узнал о флагах компилятора и все же не приблизился к решению. Я думаю, что это может быть что-то очевидное.
Мой код C ++:
#include "Rinternals.h"#include "R.h"#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 <stdint.h>
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 <stdint.h>
extern "C" {
int32_t treble(int32_t value);
}
Вы получаете ошибку, потому что компилятор C ++ название искажения метод treble
прежде чем пытаться связать с ним. extern "C"
отключает искажение
Кроме того, ваш код Rust FFI должен всегда использовать типы из libc crate; в вашем случае вы хотите libc::int32_t
,