[rust-dev] **libc::c_char to ???

Brian Anderson banderson at mozilla.com
Tue Apr 10 14:22:46 PDT 2012


On 04/10/2012 05:16 AM, Alexander Stavonin wrote:
> Hi all, it's again me.
>
> I have a C function returns array of null terminated strings. And I need to convert it to an Rust string type.
>
> C function declaration:
>
> const char** func();
>
> Rust code:
>
> native mod c {
>      fn func() ->  **libc::c_char;
> }
>
> #[test]
> fn test_func() {
>      let results = c::func();
>      // how to print all string in results???
> }
>
> I've tried next idea without success:
>
> let v: [str] = methods; // mismatched types: expected `[str]` but found `**core::libc::types::os::arch::c95::c_char` (vector vs *-ptr)
>
>
> What is the best way to do it?
Something like:

     let buf = func();
     let buflen = buf_len(buf);
     let strs = unsafe {
         let cstrs: [*c_char] = vec::unsafe::from_buf(buf, buflen);
         vec::map(cstrs) {|cstr| str::unsafe::from_c_str(cstr) }
     };

The problem is that `buf_len` doesn't exist. We could probably use some 
iterators over unsafe pointers in core. Assuming that your array of 
string pointers is null terminated, buf_len might look like:

     unsafe fn buf_len(buf: **c_char) -> uint {
         position(buf) {|i| i == ptr::null() }
     }

     // This should probably be in core::ptr
     unsafe fn position<T>(buf: *T, f: (T) -> bool) -> uint {
         let mut offset = 0u;
         loop {
             if f(*ptr::offset(ptr::addr_of(buf), offset) { ret offset; }
             else { offset += 1u; }
         }
     }



More information about the Rust-dev mailing list