On 06/16/2012 11:28 PM, Shohei Wada wrote:
Hi, list, I've read the tutorial and had a glance at the reference and
other documents.
I'm now trying to implement the GLUT library wrapper for rust, but I
got a problem.

You may be interested in collaborating with pcwalton, who also has some GLUT bindings: https://github.com/pcwalton/rust-glut


Essentially, what I want to do is to convert main()'s args: [str] to [*c_char].
I've read the document, and I found str::as_c_str() function, and the
signature is:

   fn as_c_str<T>(s: str, f: fn(*libc::c_char) -> T) -> T.

I'm wondering if it is ok to use this function as:

   let my_cstr = as_c_str(my_str) {|x| x};

It is ok, as long as you make sure that you hold the reference to my_str for at least as long as my_cstr (as_c_str is simply passing a pointer into the Rust string).


If it is OK, then it's easy to convert [str] to [*c_char].
But I'm afraid that the *c_char may not available at the outside of the closure.
Or, it may be possible that suddenly the *c_char became unavailable at outside,
like C++'s vector::iterator become unavailable when the original
vector has edited.

It should work the way you expect. Just don't modify the original string vector while using the unsafe pointers.


Currently, I assume it is NG, and I'm writing the convert function
using recursion like this:
fn rec(strs: [str], i: uint, cstrs: [mut *c_char]) unsafe {
   if strs.len() == i {
     // converted, do something with cstrs.
   } else {
     str::as_c_str(strs[i]) {|x| rec(strs, i+1u, cstrs + [x]) }
   }
}
rec(strs, 0u, [mut]);

Of course, this code will cause stack overflow when the list is very big.

This is overkill. Your other approach should work. This has come up before so it seems like a standard library function would help here.

Something vaguely like this:

let strs = .... /* Keep a reference to the string vector */
let cstrs = strs.map({ |s| as_c_str({ |buf| buf }));

And this would give you a pointer to a C array of *c_char:

vec::as_buf(strs.map({ |s| as_c_str({ |buf| buf })) { |vec_buf|
    /* vec_buf is a **c_char */
}


Anyone, do you know it is OK to use *c_char at outside of as_c_str()?
Thanks,
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev


_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to