CStr moving to
core::ffi, is there a good or recommended way to create one from an
&str without going through
CString? If not, is there a possibility of adding one? This is quite a common pattern for ffi.
It's a tricky problem because the slice has to be cloned to a buffer that is one larger, so I think any implementation is probably forced to use a const allocated array buffer. I came up with one implementation here using const generics: Rust Playground but I would kind of hope something without an extra struct wrapper would be possible. (A macro may be a better solution, but I can't figure it out).
I'm also somewhat curious how they do it in Rust For Linux, which should probably be about the most official ffi implementation out there.
CStr must have a
str won't have it. They're incompatible almost by definition. Your fixed-capacity buffer is probably the best that can be done.
Where are your
&str coming from? If it's static, you can include the
NUL and peel it away when you don't need it.
That's about what I feared but was hoping I was wrong, I think maybe I'll bring something up on GH since it's a fairly common pattern. Thanks for confirming.
I'm in the process of trying to provide safe abstractions around existing C libraries on bare metal (so
CString won't work), so I'm kind of shoehorned into working with unknown &strs coming in and needing to produce
CStrs from them.
If you're providing a wrapper around a C API, it doesn't seem unreasonable to just require users to pass
CStrs instead of
strs. Especially in a context where allocation is impossible.
Incidentally, in your playground, you need
from_bytes_until_nul, or your
to_cstr will fail due to internal
NULs when the buffer isn't sized exactly right. (On stable this probably means scan yourself or store the length...)
You're right that that is a very workable solution, but it kind of suffers from the "bubble up" problem - e.g., if the user of my wrapper gets a
&str from some function they call, then this problem of converting to
CStr still exists and is just passed on to them.
Nicer IMO to have a user of a FFI wrapper only need to worry about Rust types.
Good catch, just a little toy implementation
True, but the user of a library has more options than you as the library author do. If the strings are static they can just include the null byte in the original string, for example.
They could also have a simple allocator set up that would make conversion much simpler for them than it would be for you as the library author.
That's a good point too. I just wish there was a better solution for doing this kind of conversion in no_std - there's almost nothing out there that I can find.
I might try to wake up [RFC] A new stack-based vector by c410-f3r · Pull Request #2990 · rust-lang/rfcs · GitHub for this reason, with
CStr moving to core it would at least provide a nice option to do the conversion
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.