Some more Rusty Fun... :) (0.38.3)
This commit is contained in:
parent
c2e7f3869e
commit
d39ef1a58e
10 changed files with 157 additions and 113 deletions
|
|
@ -48,4 +48,46 @@ pub extern "C" fn fun_rust_print_string(msg: *const core::ffi::c_char) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
// Return a newly allocated duplicate of the given C string.
|
||||
// Caller (C side) must free using fun_rust_string_free.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fun_rust_echo_string(input: *const core::ffi::c_char) -> *mut core::ffi::c_char {
|
||||
use core::ffi::CStr;
|
||||
unsafe {
|
||||
if input.is_null() {
|
||||
// allocate empty string
|
||||
let v = Vec::<u8>::from([0u8]);
|
||||
return v.leak().as_mut_ptr() as *mut core::ffi::c_char;
|
||||
}
|
||||
match CStr::from_ptr(input).to_str() {
|
||||
Ok(s) => {
|
||||
let mut v = s.as_bytes().to_vec();
|
||||
v.push(0); // NUL-terminate
|
||||
v.leak().as_mut_ptr() as *mut core::ffi::c_char
|
||||
}
|
||||
Err(_) => {
|
||||
// On invalid UTF-8, still duplicate bytes as-is
|
||||
let c = CStr::from_ptr(input);
|
||||
let mut v = c.to_bytes().to_vec();
|
||||
v.push(0);
|
||||
v.leak().as_mut_ptr() as *mut core::ffi::c_char
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Free a C string previously returned by fun_rust_echo_string
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fun_rust_string_free(ptr: *mut core::ffi::c_char) {
|
||||
if ptr.is_null() { return; }
|
||||
unsafe {
|
||||
// Reconstruct a Vec<u8> so Rust will free it when it drops
|
||||
// Determine length by scanning for NUL
|
||||
let mut len: usize = 0;
|
||||
while *ptr.add(len) != 0 { len += 1; }
|
||||
let slice = core::slice::from_raw_parts_mut(ptr as *mut u8, len + 1);
|
||||
let _ = Vec::from_raw_parts(slice.as_mut_ptr(), len + 1, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// No custom panic handler; use std default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue