I work on a Rust
library used, through C
headers, in a Swift
UI.
I can read from Swift in Rust, but I can't write right away to Swift (so from Rust) what I've just read.
--
Basically, I get to convert successfully in String
an *const i8
saying hello world
.
But the same String
fails to be handled with consistency by as_ptr()
(and so being parsed as UTF-8 in Swift) =>
Swift
sendhello world
as*const i8
Rust
handle it throughlet input: &str
successfully (#1 print inget_message()
) => rightly printshello world
- Now I can't convert this
input
&str
to a pointer again:
- the pointer can't be decoded by
Swift
- the "pointer encoding" changes at every call of the function (should be always the same output, as for
"hello world".as_ptr()
)
Basically, why
"hello world".as_ptr()
always have the same output and can be decoded by Swift- when
input.as_ptr()
has a different output every time called and can't never be decoded by Swift (where printinginput
rightly returnshello world
)?
Do you guys have ideas?
#[derive(Debug)]
#[repr(C)]
pub struct MessageC {
pub message_bytes: *const u8,
pub message_len: libc::size_t,
}
/// # Safety
/// call of c_string_safe from Swift
/// => https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.from_ptr
unsafe fn c_string_safe(cstring: *const i8) -> String {
CStr::from_ptr(cstring).to_string_lossy().into_owned()
}
/// # Safety
/// call of c_string_safe from Swift
/// => https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.from_ptr
/// on `async extern "C"` => <https://stackoverflow.com/a/52521592/7281870>
#[no_mangle]
#[tokio::main] // allow async function, needed to call here other async functions (not this example but needed)
pub async unsafe extern "C" fn get_message(
user_input: *const i8,
) -> MessageC {
let input: &str = &c_string_safe(user_input);
println!("from Swift: {}", input); // [consistent] from Swift: hello world
println!("converted to ptr: {:?}", input.as_ptr()); // [inconsistent] converted to ptr: 0x60000079d770 / converted to ptr: 0x6000007b40b0
println!("directly to ptr: {:?}", "hello world".as_ptr()); // [consistent] directly to ptr: 0x1028aaf6f
MessageC {
message_bytes: input.as_ptr(),
message_len: input.len() as libc::size_t,
}
}