Hi! First of all, if you are writing custom bindings to sqlite not only to learn Rust, I'd suggest using already existing bindings [1]. That way you probably won't have to deal with low-level C integration stuff.
However, if you want to learn how to write C bindings, you should probably start with reading an official tutorial [2] on foreign function interface. That way you will learn that Rust strings are not C-compatible, they are not terminated by zero byte, so you can't get a pointer from a string and pass it to a C routine directly. In order to properly convert &str to *c_char you have to use various conversion utilities, the most simple one being with_c_str() method: let s = "some_string"; let result = s.with_c_str(|char_ptr| { // call C functions, char_ptr is a *c_char pointer // after this block finishes, a buffer pointed to by char_ptr will be freed some_result }); Here [3] is the relevant piece of documentation on C strings conversions. Your second example is also incorrect. Converting C strings to static slices is highly unsafe, for example, it will crash your program if the string is not a valid UTF-8 sequence, not to mention lifetime issues. There is a reason why it is placed in such inconvenient place as `std::str::raw`. You shouldn't use it. Instead you should use std::c_str::CString structure to wrap C strings. BTW, this structure also forces you to think about ownership. I don't know much about sqlite API, but if you're not supposed to free a string returned by sqlite3_errmsg() function, you should create CString like this CString::new(sqlite3_errmsg(*ppDb), false) false means that this CString won't own the buffer and won't free it when it goes out of scope. When you have CString structure, you can get a string slice out of it using as_str() method. This all is documented here [4]. [1]: https://github.com/linuxfood/rustsqlite. [2]: http://static.rust-lang.org/doc/master/guide-ffi.html [3]: http://static.rust-lang.org/doc/master/std/c_str/index.html [4]: http://static.rust-lang.org/doc/master/std/c_str/struct.CString.html 2014-05-10 18:14 GMT+04:00 Christophe Pedretti <christophe.pedre...@gmail.com>: > Hi all, > > i am writing a wrapper to an SQLite database. > > If i use : > extern { fn sqlite3_open(filename: *c_char, ppDb : **mut ()) -> c_int; } > i can not use : > let ppDb : **mut () = RawPtr::null(); > unsafe { res=sqlite3_open(filename.as_ptr(), ppDb); > because as_ptr() returns an *u8 and c_char is a i8, so i have to use > extern { fn sqlite3_open(filename: *c_uchar, ppDb : **mut ()) -> c_int; } > > > Now, suppose i use : > extern { fn sqlite3_errmsg(pDb : *mut ()) -> *c_uchar; } > i can not use : > let mut desc=""; { unsafe { desc = > c_str_to_static_slice(sqlite3_errmsg(*ppDb)); } } > because c_str_to_static_slice taks a *c_char (so an i8) as argument, so i > have to use > extern { fn sqlite3_errmsg(pDb : *mut ()) -> *c_char; } > > If the second example is quite logical, what about the first one ? > how to convert &str -> *c_char ? > > thanks > > -- > Christophe > http://chris-pe.github.io/Rustic/ > > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev