Skip to content

Commit e278d15

Browse files
Implement rev
1 parent a42346c commit e278d15

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

R/hello.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ hello2 <- function(name) {
1818
.Call(hello_wrapper2, name)
1919
}
2020

21+
#' @export
22+
#' @rdname hellorust
23+
#' @examples rev()
24+
#' @useDynLib hellorust rev_wrapper
25+
rev <- function(x) {
26+
.Call(rev_wrapper, x)
27+
}
28+
2129
#' @export
2230
#' @rdname hellorust
2331
#' @examples random()

src/myrustlib/api.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@
44
extern "C" {
55
#endif
66

7+
// A struct to pass the results from Rust to C
8+
typedef struct
9+
{
10+
double *data;
11+
uint32_t len;
12+
} Slice;
13+
714
char * string_from_rust();
815
char * string_from_rust2(const char*);
16+
Slice rev_slice(Slice);
917
int32_t random_number();
1018
void run_threads();
1119

src/myrustlib/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ extern crate rand;
66
mod hello;
77
mod random;
88
mod mythreads;
9+
mod slice;
910

1011
// Export functions called by R
1112
pub use hello::string_from_rust;
13+
pub use hello::string_from_rust2;
1214
pub use random::random_number;
1315
pub use mythreads::run_threads;
16+
pub use slice::rev_slice;
17+
pub use slice::Slice;

src/myrustlib/src/slice.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use std;
2+
use std::os::raw::{c_double, c_uint};
3+
4+
#[repr(C)]
5+
pub struct Slice {
6+
data: *mut c_double,
7+
len: c_uint,
8+
}
9+
10+
#[no_mangle]
11+
pub extern fn rev_slice(s: Slice) -> Slice {
12+
// convert from Slice to Rust slice
13+
let s = unsafe { std::slice::from_raw_parts_mut(s.data, s.len as _) };
14+
15+
let mut v = s.to_vec();
16+
v.reverse();
17+
let len = v.len();
18+
19+
let v_ptr = v.as_mut_ptr();
20+
std::mem::forget(v);
21+
22+
Slice {
23+
data: v_ptr,
24+
len: len as _,
25+
}
26+
}

src/wrapper.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ SEXP hello_wrapper2(SEXP name){
1515
return Rf_ScalarString(Rf_mkCharCE(res, CE_UTF8));
1616
}
1717

18+
SEXP rev_wrapper(SEXP x){
19+
Slice s = {REAL(x), Rf_length(x)};
20+
Slice s_rev = rev_slice(s);
21+
22+
SEXP out = PROTECT(Rf_allocVector(REALSXP, s_rev.len));
23+
for (int i = 0; i < s_rev.len; i++) {
24+
SET_REAL_ELT(out, i, s_rev.data[i]);
25+
}
26+
UNPROTECT(1);
27+
28+
return out;
29+
}
30+
1831

1932
SEXP random_wrapper(){
2033
return Rf_ScalarInteger(random_number());
@@ -29,6 +42,7 @@ SEXP threads_wapper(){
2942
static const R_CallMethodDef CallEntries[] = {
3043
{"hello_wrapper", (DL_FUNC) &hello_wrapper, 0},
3144
{"hello_wrapper2", (DL_FUNC) &hello_wrapper2, 0},
45+
{"rev_wrapper", (DL_FUNC) &rev_wrapper, 0},
3246
{"random_wrapper", (DL_FUNC) &random_wrapper, 0},
3347
{"threads_wapper", (DL_FUNC) &threads_wapper, 0},
3448
{NULL, NULL, 0}

0 commit comments

Comments
 (0)