The (unsafe) API for "indexing" into a pointer is to use the .add(i) method for pointers and dereference the result. The example code in the linked documentation also helps illustrate the exact way this would look. Rust is known to be a bit less ergonomic to work with when you use with (unsafe) raw pointers, so indexing syntax isn't directly supported. Another option could be to build a &mut [*mut u8] slice first, then indexing and even directly iterating would work as expected. Building such a slice could be achieved via from_raw_parts_mut in std::slice - Rust.
Yes Sebastian, I have had written the C struct first but at the last moment, changed my mind and re-wrote it in Rust syntax. The remnant is visible.
Thank you for pointing it out, I will be more careful next time.
for a_device in slice::from_raw_parts_mut(
dev_info.detected_device_names,
dev_info.detected_device_len.try_into().unwrap(),
) {
// ...
}
Arguably, depending on the use-case, you could also be working with an immutable slice, so which would like the same but without the _mut ending in the method name. As it stands above, the type this loop gives is &mut *mut u8 (Assuming detected_devicd_names is a *mut *mut u8.) Which you can dereference as needed to read (or possibly even replace by something else) one of the *mut u8s. How to work with those, presumably zero-terminated strings of some (not specified here) encoding, is then the next step that I haven't discussed yet.
Given this Rust to C interface, I also wonder what your ownership story looks like, and who will, in what manner, clean up the allocations that would likely be involved in this example.
I couldn’t agree more. BTW is there any elegant way for safety allocation across FFI?, like Rust take over the C-String allocated by C functions, or some else.
There's a difference between std::ptr::slice_from_raw_parts_mut and std::slice::from_raw_parts_mut The error indicates you might have used the ptr one.
By the way, if you only want to read anyways, then you could use slice::from_raw_parts to create an immutable slice, too. If the Rust code is only supposed to read the data anyways, you could work with *const *const u8 in the first place, too, to make that more clearly documented.
The next step to read the actual string data could be to use something like CStr::from_ptr. Having used u8 as a stand-in for C’s char, to make using CStr::from_ptr easier to use, you could also work with *const *const i8 from the start.
I’ve written a small example with a test case here: Rust Playground