How to address raw pointer as array


#1

Hi all,

I’m struggling to figure out how to handle an ffi function that returns an array of pointers that is null-terminated. I just want to convert this array (which is **char array of C strings) into anything rust native. Ultimately it will be a HashSet, but if I can get it into a Vec that would be great.

I’m stuck on trying to treat the raw pointer as an array of sorts, so I can count how many elements I have. My current really ugly approach is to use std::slice::from_raw_parts, but that requires me to provide a length, which I won’t know until I’ve looped my way through the code. I suppose I could just write a little C function to do this, but that seems rather ugly to me.

Here is what I’ve got so far (which is incomplete):

fn null_c_array_to_osstr(a: *const *const c_char) -> Vec<OsString> {
    let sl = unsafe { std::slice::from_raw_parts(a, 10000) };
    let mut count = 0;
    while sl[count] != std::ptr::null() {
        count += 1;
    }
    let sl = unsafe { std::slice::from_raw_parts(a, count) };
    let mut v = vec![];   
    v
}

Any suggestions? It seems like there must be some unsafe and fundamental function for handling raw pointers as arrays that I’m missing!

David


#2

I would do something like this:

    let mut count = 0;
    let mut p = a;
    unsafe {
        while *p != std::ptr::null() {
            count += 1;
            p = p.offset(1);
        }
    }

This treats the pointer as a pointer, rather than an array. These are much more distinct in Rust than they are in C; as you noted, Rust doesn’t have the idea of an array with unknown length.


#3

Ah, it was the offset function that I didn’t notice! I looked for something like this, but only tried addition of an integer, which unsurprisingly didn’t work.