Skip to content

Commit

Permalink
Implement rev
Browse files Browse the repository at this point in the history
  • Loading branch information
yutannihilation committed Sep 15, 2020
1 parent a42346c commit e278d15
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 0 deletions.
8 changes: 8 additions & 0 deletions R/hello.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ hello2 <- function(name) {
.Call(hello_wrapper2, name)
}

#' @export
#' @rdname hellorust
#' @examples rev()
#' @useDynLib hellorust rev_wrapper
rev <- function(x) {
.Call(rev_wrapper, x)
}

#' @export
#' @rdname hellorust
#' @examples random()
Expand Down
8 changes: 8 additions & 0 deletions src/myrustlib/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@
extern "C" {
#endif

// A struct to pass the results from Rust to C
typedef struct
{
double *data;
uint32_t len;
} Slice;

char * string_from_rust();
char * string_from_rust2(const char*);
Slice rev_slice(Slice);
int32_t random_number();
void run_threads();

Expand Down
4 changes: 4 additions & 0 deletions src/myrustlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ extern crate rand;
mod hello;
mod random;
mod mythreads;
mod slice;

// Export functions called by R
pub use hello::string_from_rust;
pub use hello::string_from_rust2;
pub use random::random_number;
pub use mythreads::run_threads;
pub use slice::rev_slice;
pub use slice::Slice;
26 changes: 26 additions & 0 deletions src/myrustlib/src/slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std;
use std::os::raw::{c_double, c_uint};

#[repr(C)]
pub struct Slice {
data: *mut c_double,
len: c_uint,
}

#[no_mangle]
pub extern fn rev_slice(s: Slice) -> Slice {
// convert from Slice to Rust slice
let s = unsafe { std::slice::from_raw_parts_mut(s.data, s.len as _) };

let mut v = s.to_vec();
v.reverse();
let len = v.len();

let v_ptr = v.as_mut_ptr();
std::mem::forget(v);

Slice {
data: v_ptr,
len: len as _,
}
}
14 changes: 14 additions & 0 deletions src/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ SEXP hello_wrapper2(SEXP name){
return Rf_ScalarString(Rf_mkCharCE(res, CE_UTF8));
}

SEXP rev_wrapper(SEXP x){
Slice s = {REAL(x), Rf_length(x)};
Slice s_rev = rev_slice(s);

SEXP out = PROTECT(Rf_allocVector(REALSXP, s_rev.len));
for (int i = 0; i < s_rev.len; i++) {
SET_REAL_ELT(out, i, s_rev.data[i]);
}
UNPROTECT(1);

return out;
}


SEXP random_wrapper(){
return Rf_ScalarInteger(random_number());
Expand All @@ -29,6 +42,7 @@ SEXP threads_wapper(){
static const R_CallMethodDef CallEntries[] = {
{"hello_wrapper", (DL_FUNC) &hello_wrapper, 0},
{"hello_wrapper2", (DL_FUNC) &hello_wrapper2, 0},
{"rev_wrapper", (DL_FUNC) &rev_wrapper, 0},
{"random_wrapper", (DL_FUNC) &random_wrapper, 0},
{"threads_wapper", (DL_FUNC) &threads_wapper, 0},
{NULL, NULL, 0}
Expand Down

0 comments on commit e278d15

Please sign in to comment.