From d85d389b09a0c7805e2b7fb041c4ce7b1d0fd5a2 Mon Sep 17 00:00:00 2001 From: CGMossa Date: Mon, 3 Jun 2024 12:13:46 +0200 Subject: [PATCH] added routine to free the leaked rust `CString`. (#22) --- src/myrustlib/api.h | 1 + src/myrustlib/src/hello.rs | 7 ++++++- src/wrapper.c | 6 +++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/myrustlib/api.h b/src/myrustlib/api.h index 16ad389..723e695 100644 --- a/src/myrustlib/api.h +++ b/src/myrustlib/api.h @@ -5,6 +5,7 @@ extern "C" { #endif char * string_from_rust(void); +void free_string_from_rust(char*); int32_t random_number(void); void run_threads(void); diff --git a/src/myrustlib/src/hello.rs b/src/myrustlib/src/hello.rs index 925cc15..3186a21 100644 --- a/src/myrustlib/src/hello.rs +++ b/src/myrustlib/src/hello.rs @@ -2,7 +2,12 @@ use std::ffi::CString; use std::os::raw::c_char; #[no_mangle] -pub extern fn string_from_rust() -> *const c_char { +pub extern "C" fn string_from_rust() -> *const c_char { let s = CString::new("Hello ピカチュウ !").unwrap(); s.into_raw() } + +#[no_mangle] +pub extern "C" fn free_string_from_rust(ptr: *mut c_char) { + let _ = unsafe { CString::from_raw(ptr) }; +} diff --git a/src/wrapper.c b/src/wrapper.c index 23dac87..9e8f131 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -7,7 +7,11 @@ // Actual Wrappers SEXP hello_wrapper(void){ - return Rf_ScalarString(Rf_mkCharCE(string_from_rust(), CE_UTF8)); + char* hello_rust = string_from_rust(); + SEXP hello_world_string = PROTECT(Rf_mkCharCE(hello_rust, CE_UTF8)); + free_string_from_rust(hello_rust); + UNPROTECT(1); + return Rf_ScalarString(hello_world_string); } SEXP random_wrapper(void){