I have a C function returning a pointer:
type MYSQL_RES_REF = *mut c_void;
type MYSQL_ROW = *const *const c_char;
#[no_mangle]
extern "C" {
fn mysql_fetch_row(res: MYSQL_RES_REF) -> MYSQL_ROW;
}
let pointer = mysql_fetch_row(self.res);
let row_p = match pointer {
p if p == (0 as *const *const c_char) => panic!(),
p => p,
};
let field: &[u8] = unsafe { ffi::c_str_to_bytes(row_p[i]) };
but attempting to index it (the last line) results in an error:
error: cannot index a value of type `*const *const i8`
I wonder if std::c_vec
was what I wanted, but apparently that has been removed.
In Rust, arrays are created using square brackets [] and their size needs to be known at compile time. An array whose size is not defined is called a slice.
Just as with methods, Rust will also insert dereference operations on a repeatedly to find an implementation. Indices are zero-based for arrays and slices.
There is no way to do this in stable Rust; arrays cannot have values added or removed at runtime; their lengths are fixed at compile time.
Arrays of any size implement the following traits if the element type allows it: Copy. Clone. Debug.
There is an offset
method on pointers which can be used as:
let new_p = p.offset(i);
to get a pointer i
elements away from the current one. It is not bounds-checked, obviously, so you must ensure it stays within the bounds (or one-past-the-end).
There is also an unstable offset
intrinsic.
If you have the length of your C array, you can convert the pointer and the length into a Rust slice and then use all the existing support for slices:
use libc::size_t; // 0.2.51
use std::slice;
/// Our opaque C type
#[repr(C)]
struct MyCType {
private: [u8; 0],
}
extern "C" {
fn get_ptr_and_len(len: *mut size_t) -> *const MyCType;
fn do_something_with_type(v: *const MyCType);
}
fn ptr_and_len() {
unsafe {
let mut len = 0;
let ptr = get_ptr_and_len(&mut len);
let slice = slice::from_raw_parts(ptr, len);
// Indexing
do_something_with_type(&slice[42]);
// Iteration
for v in slice {
do_something_with_type(v);
}
}
}
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With