I'm using rust to call c++, there are structs generated by bindgen
and cc
. The struct fields type is like [i8;11]
or [i8;n]
. I want to set these fields.
How to write a common function to transform rust String/CStr/CString
to i8
/c_char
array?
There are two problems you have to be aware of:
encoding_rs
to convert the encoding properly.Let's assume C/C++ strings are also encoded in UTF-8 (again, an assumption you can not make on Windows). Then, you can convert it (for example) like that:
use std::ffi::CString;
fn main() {
// Fill with dummy data to 'simulate' the situation of uninitialized memory
let mut c_array = [42i8; 11];
// The data that should get written into c_array
let rust_string = String::from("Hello!");
// Convert to CString, required for FFI
let rust_cstring = CString::new(rust_string).unwrap();
// Extract null-terminated raw data
let byteslice = rust_cstring.as_bytes_with_nul();
// Write data. Note that this will panic if `byteslice` is longer than `c_array`.
let mut byteslice_iter_i8 = byteslice.iter().map(|v| *v as i8);
c_array[0..byteslice.len()].fill_with(|| byteslice_iter_i8.next().unwrap());
println!("{:?}", c_array);
}
[72, 101, 108, 108, 111, 33, 0, 42, 42, 42, 42]
There are of course other ways, and this one probably isn't the absolute single best way to do that, but I hope that this managed to demonstrate the basic principle.