-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrust_add.rs
93 lines (79 loc) · 2.42 KB
/
rust_add.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
mod bindings {
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
include!("bindings/R.rs");
#[non_exhaustive]
#[repr(transparent)]
#[derive(Debug)]
pub struct SEXPREC(std::ffi::c_void);
// TODO: What should this be? libc::FILE?
pub enum FILE {}
include!("bindings/R_ext/Boolean.rs");
include!("bindings/R_ext/Complex.rs");
include!("bindings/R_ext/Rdynload.rs");
include!("custom_bindings/custom_Rdynload.rs");
include!("bindings/Rinternals.rs");
}
#[allow(unused_imports)]
use bindings::*;
include!("bindings/R_ext/Error.rs");
#[no_mangle]
unsafe extern "C" fn add(x: SEXP, y: SEXP) -> SEXP {
// Ensure inputs are numeric vectors of length 1
if Rf_isReal(x) == Rboolean::FALSE || Rf_xlength(x) != 1 {
Rf_error(
c"x must be a numeric value"
.as_ptr(),
);
}
if Rf_isReal(y) == Rboolean::FALSE || Rf_xlength(y) != 1 {
Rf_error(
c"y must be a numeric value"
.as_ptr(),
);
}
// Retrieve the numeric values
let x_value = REAL(x).read();
let y_value = REAL(y).read();
// Perform the addition
let result = Rf_protect(Rf_allocVector(SEXPTYPE::REALSXP, 1));
REAL(result).write(x_value + y_value);
Rf_unprotect(1);
result
}
#[no_mangle]
pub extern "C" fn ultimate_answer() -> SEXP {
unsafe { Rf_ScalarInteger(4242_i32) }
}
// #[lang = "eh_personality"]
// extern "C" fn rust_eh_personality() {}
// #[allow(non_snake_case)]
// pub unsafe extern "C" fn R_init_hellorustc(dll: *mut DllInfo) {
// use std::ptr;
// let call_entries = [
// R_CallMethodDef {
// name: c"ultimate_answer".as_ptr(),
// // fun: Some(std::mem::transmute(ultimate_answer)),
// // fun: Some(ultimate_answer as unsafe extern "C" fn() -> *mut std::ffi::c_void),
// fun: Some(std::mem::transmute(&ultimate_answer)),
// numArgs: 0,
// },
// R_CallMethodDef {
// name: ptr::null(),
// fun: None,
// numArgs: 0,
// },
// ];
// R_registerRoutines(
// dll,
// ptr::null(),
// call_entries.as_ptr(),
// ptr::null(),
// ptr::null(),
// );
// R_useDynamicSymbols(dll, Rboolean::FALSE);
// /* Register routines,
// allocate resources. */
// }