1 use std::ffi::{CStr, CString};
9 /// let a = call_rust_from_c::answer();
10 /// assert_eq!(a, 42);
13 // C 'int'; it does not actually hurt to have more specific types such as int32_t, but it's good to know that plain ints work
14 pub extern "C" fn answer() -> raw::c_int {
19 pub extern "C" fn r_strlen(s: *const raw::c_char) -> usize {
20 unsafe { CStr::from_ptr(s) }.to_bytes().len()
23 /// Return a vector of pointers as C pointer array
25 /// The memory of `vec` gets leaked, as otherwise Rust would free it once the vector
26 /// goes out of scope, and C would access invalid memory.
27 fn return_c_vec<T>(mut vec: Vec<T>) -> *mut T {
28 let p = vec.as_mut_ptr();
29 // unref vector so that it does not get freed when going out of scope
30 std::mem::forget(vec);
35 pub extern "C" fn r_strlist() -> *mut *const raw::c_uchar {
43 fn impl_grep<'a>(needle: &str, haystack: &'a str) -> Vec<&'a str> {
45 .filter(|line| line.contains(needle))
50 pub extern "C" fn r_grep(needle: *const raw::c_char, haystack: *const raw::c_char) -> *mut *const raw::c_char {
51 let haystack_cstr = unsafe { CStr::from_ptr(haystack).to_str() }.unwrap();
52 let strvec = impl_grep(unsafe { CStr::from_ptr(needle).to_str().unwrap() }, haystack_cstr);
54 // Vec[str] -> Vec[const char*]
55 let p_vec: Vec<_> = strvec.into_iter()
57 let s = CString::new(s).unwrap();
73 assert_eq!(answer(), 42);
78 assert_eq!(impl_grep("ell", "Hello\nworld\ncan you tell?"), vec!["Hello", "can you tell?"]);