File tree Expand file tree Collapse file tree 4 files changed +25
-4
lines changed
Expand file tree Collapse file tree 4 files changed +25
-4
lines changed Original file line number Diff line number Diff line change @@ -13,7 +13,10 @@ typedef struct
1313
1414char * string_from_rust ();
1515char * string_from_rust2 (const char * );
16+
1617Slice rev_slice (Slice );
18+ void free_slice (Slice );
19+
1720int32_t random_number ();
1821void run_threads ();
1922
Original file line number Diff line number Diff line change @@ -14,4 +14,5 @@ pub use hello::string_from_rust2;
1414pub use random:: random_number;
1515pub use mythreads:: run_threads;
1616pub use slice:: rev_slice;
17+ pub use slice:: free_slice;
1718pub use slice:: Slice ;
Original file line number Diff line number Diff line change @@ -8,7 +8,7 @@ pub struct Slice {
88}
99
1010#[ no_mangle]
11- pub extern fn rev_slice ( s : Slice ) -> Slice {
11+ pub extern "C" fn rev_slice ( s : Slice ) -> Slice {
1212 // convert from Slice to Rust slice
1313 let s = unsafe { std:: slice:: from_raw_parts_mut ( s. data , s. len as _ ) } ;
1414
@@ -24,3 +24,14 @@ pub extern fn rev_slice(s: Slice) -> Slice {
2424 len : len as _ ,
2525 }
2626}
27+
28+ // c.f. https://users.rust-lang.org/t/how-to-return-byte-array-from-rust-function-to-ffi-c/18136/4
29+ #[ no_mangle]
30+ pub extern "C" fn free_slice ( s : Slice ) {
31+ // convert to Rust slice
32+ let s = unsafe { std:: slice:: from_raw_parts_mut ( s. data , s. len as _ ) } ;
33+ let s = s. as_mut_ptr ( ) ;
34+ unsafe {
35+ Box :: from_raw ( s) ;
36+ }
37+ }
Original file line number Diff line number Diff line change 55// Import C headers for rust API
66#include "myrustlib/api.h"
77
8+ // Need to include to use memcpy()
9+ #include <string.h>
10+
811// Actual Wrappers
912SEXP hello_wrapper (){
1013 return Rf_ScalarString (Rf_mkCharCE (string_from_rust (), CE_UTF8 ));
@@ -20,11 +23,14 @@ SEXP rev_wrapper(SEXP x){
2023 Slice s_rev = rev_slice (s );
2124
2225 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+ memcpy (REAL (out ), s_rev .data , s .len * sizeof (double ));
27+ // AS soon as the Rust-allocated memory become no longer in use, free it.
28+ // Since Rust's allocator is different from C's allocator, this needs to be
29+ // freed on C's side.
30+ free_slice (s_rev );
2631 UNPROTECT (1 );
2732
33+
2834 return out ;
2935}
3036
You can’t perform that action at this time.
0 commit comments