Struct CString
struct CString { ... }
A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the middle.
This type serves the purpose of being able to safely generate a C-compatible string from a Rust byte slice or vector. An instance of this type is a static guarantee that the underlying bytes contain no interior 0 bytes ("nul characters") and that the final byte is 0 ("nul terminator").
CString is to &[CStr] as String is to &str: the former
in each pair are owned strings; the latter are borrowed
references.
Creating a CString
A CString is created from either a byte slice or a byte vector,
or anything that implements [Into]<[Vec]<[u8]>> (for
example, you can build a CString straight out of a String or
a &str, since both implement that trait).
You can create a CString from a literal with CString::from(c"Text").
The CString::new method will actually check that the provided &[[u8]]
does not have 0 bytes in the middle, and return an error if it
finds one.
Extracting a raw pointer to the whole C string
CString implements an [as_ptr]CStr::as_ptr method through the Deref
trait. This method will give you a *const c_char which you can
feed directly to extern functions that expect a nul-terminated
string, like C's strdup(). Notice that [as_ptr]CStr::as_ptr returns a
read-only pointer; if the C code writes to it, that causes
undefined behavior.
Extracting a slice of the whole C string
Alternatively, you can obtain a &[[u8]] slice from a
CString with the CString::as_bytes method. Slices produced in this
way do not contain the trailing nul terminator. This is useful
when you will be calling an extern function that takes a *const u8 argument which is not necessarily nul-terminated, plus another
argument with the length of the string — like C's strndup().
You can of course get the slice's length with its
[len][slice::len] method.
If you need a &[[u8]] slice with the nul terminator, you
can use CString::as_bytes_with_nul instead.
Once you have the kind of slice you need (with or without a nul
terminator), you can call the slice's own
[as_ptr][slice::as_ptr] method to get a read-only raw pointer to pass to
extern functions. See the documentation for that function for a
discussion on ensuring the lifetime of the raw pointer.
Examples
# fn main() {
use std::ffi::CString;
use std::os::raw::c_char;
extern "C" {
fn my_printer(s: *const c_char);
}
// We are certain that our string doesn't have 0 bytes in the middle,
// so we can .expect()
let c_to_print = CString::new("Hello, world!").expect("CString::new failed");
unsafe {
my_printer(c_to_print.as_ptr());
}
# }
Safety
CString is intended for working with traditional C-style strings
(a sequence of non-nul bytes terminated by a single nul byte); the
primary use case for these kinds of strings is interoperating with C-like
code. Often you will need to transfer ownership to/from that external
code. It is strongly recommended that you thoroughly read through the
documentation of CString before use, as improper ownership management
of CString instances can lead to invalid memory accesses, memory leaks,
and other memory errors.
Implementations
impl CString
fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError>Creates a new C-compatible string from a container of bytes.
This function will consume the provided data and use the underlying bytes to construct a new string, ensuring that there is a trailing 0 byte. This trailing 0 byte will be appended by this function; the provided data should not contain any 0 bytes in it.
Examples
use std::ffi::CString; use std::os::raw::c_char; extern "C" { fn puts(s: *const c_char); } let to_print = CString::new("Hello!").expect("CString::new failed"); unsafe { puts(to_print.as_ptr()); }Errors
This function will return an error if the supplied bytes contain an internal 0 byte. The
NulErrorreturned will contain the bytes as well as the position of the nul byte.unsafe fn from_vec_unchecked(v: Vec<u8>) -> SelfCreates a C-compatible string by consuming a byte vector, without checking for interior 0 bytes.
Trailing 0 byte will be appended by this function.
This method is equivalent to
CString::newexcept that no runtime assertion is made thatvcontains no 0 bytes, and it requires an actual byte vector, not anything that can be converted to one with Into.Examples
use CString; let raw = b"foo".to_vec; unsafeunsafe fn from_raw(ptr: *mut c_char) -> CStringRetakes ownership of a
CStringthat was transferred to C viaCString::into_raw.Additionally, the length of the string will be recalculated from the pointer.
Safety
This should only ever be called with a pointer that was earlier obtained by calling
CString::into_raw, and the memory it points to must not be accessed through any other pointer during the lifetime of reconstructedCString. Other usage (e.g., trying to take ownership of a string that was allocated by foreign code) is likely to lead to undefined behavior or allocator corruption.This function does not validate ownership of the raw pointer's memory. A double-free may occur if the function is called twice on the same raw pointer. Additionally, the caller must ensure the pointer is not dangling.
It should be noted that the length isn't just "recomputed," but that the recomputed length must match the original length from the
CString::into_rawcall. This means theCString::into_raw/from_rawmethods should not be used when passing the string to C functions that can modify the string's length.Note: If you need to borrow a string that was allocated by foreign code, use
CStr. If you need to take ownership of a string that was allocated by foreign code, you will need to make your own provisions for freeing it appropriately, likely with the foreign code's API to do that.Examples
Creates a
CString, pass ownership to anexternfunction (via raw pointer), then retake ownership withfrom_raw:use std::ffi::CString; use std::os::raw::c_char; extern "C" { fn some_extern_function(s: *mut c_char); } let c_string = CString::from(c"Hello!"); let raw = c_string.into_raw(); unsafe { some_extern_function(raw); let c_string = CString::from_raw(raw); }fn into_raw(self: Self) -> *mut c_charConsumes the
CStringand transfers ownership of the string to a C caller.The pointer which this function returns must be returned to Rust and reconstituted using
CString::from_rawto be properly deallocated. Specifically, one should not use the standard Cfree()function to deallocate this string.Failure to call
CString::from_rawwill lead to a memory leak.The C side must not modify the length of the string (by writing a nul byte somewhere inside the string or removing the final one) before it makes it back into Rust using
CString::from_raw. See the safety section inCString::from_raw.Examples
use CString; let c_string = from; let ptr = c_string.into_raw; unsafefn into_string(self: Self) -> Result<String, IntoStringError>Converts the
CStringinto aStringif it contains valid UTF-8 data.On failure, ownership of the original
CStringis returned.Examples
use CString; let valid_utf8 = vec!; let cstring = new.expect; assert_eq!; let invalid_utf8 = vec!; let cstring = new.expect; let err = cstring.into_string.err.expect; assert_eq!;fn into_bytes(self: Self) -> Vec<u8>Consumes the
CStringand returns the underlying byte buffer.The returned buffer does not contain the trailing nul terminator, and it is guaranteed to not have any interior nul bytes.
Examples
use CString; let c_string = from; let bytes = c_string.into_bytes; assert_eq!;fn into_bytes_with_nul(self: Self) -> Vec<u8>Equivalent to [
CString::into_bytes()] except that the returned vector includes the trailing nul terminator.Examples
use CString; let c_string = from; let bytes = c_string.into_bytes_with_nul; assert_eq!;fn as_bytes(self: &Self) -> &[u8]Returns the contents of this
CStringas a slice of bytes.The returned slice does not contain the trailing nul terminator, and it is guaranteed to not have any interior nul bytes. If you need the nul terminator, use
CString::as_bytes_with_nulinstead.Examples
use CString; let c_string = from; let bytes = c_string.as_bytes; assert_eq!;fn as_bytes_with_nul(self: &Self) -> &[u8]Equivalent to [
CString::as_bytes()] except that the returned slice includes the trailing nul terminator.Examples
use CString; let c_string = from; let bytes = c_string.as_bytes_with_nul; assert_eq!;fn as_c_str(self: &Self) -> &CStrExtracts a
CStrslice containing the entire string.Examples
use ; let c_string = from; let cstr = c_string.as_c_str; assert_eq!;fn into_boxed_c_str(self: Self) -> Box<CStr>Converts this
CStringinto a boxedCStr.Examples
let c_string = c"foo".to_owned; let boxed = c_string.into_boxed_c_str; assert_eq!;unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> SelfConverts a
[Vec]<[u8]>to aCStringwithout checking the invariants on the givenVec.Safety
The given
Vecmust have one nul byte as its last element. This means it cannot be empty nor have any other nul byte anywhere else.Example
use CString; assert_eq!;fn from_vec_with_nul(v: Vec<u8>) -> Result<Self, FromVecWithNulError>Attempts to convert a
[Vec]<[u8]>to aCString.Runtime checks are present to ensure there is only one nul byte in the
Vec, its last element.Errors
If a nul byte is present and not the last element or no nul bytes is present, an error will be returned.
Examples
A successful conversion will produce the same result as
CString::newwhen called without the ending nul byte.use CString; assert_eq!;An incorrectly formatted
Vecwill produce an error.use ; // Interior nul byte let _: FromVecWithNulError = from_vec_with_nul.unwrap_err; // No nul byte let _: FromVecWithNulError = from_vec_with_nul.unwrap_err;
impl AsRef for CString
fn as_ref(self: &Self) -> &CStr
impl Borrow for CString
fn borrow(self: &Self) -> &CStr
impl Clone for CString
fn clone(self: &Self) -> CString
impl Debug for CString
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl Default for CString
fn default() -> CStringCreates an empty
CString.
impl Deref for CString
fn deref(self: &Self) -> &CStr
impl Drop for CString
fn drop(self: &mut Self)
impl Eq for CString
impl Freeze for CString
impl From for CString
fn from(v: Vec<NonZero<u8>>) -> CStringConverts a
[Vec]<[NonZero]<[u8]>>into aCStringwithout copying nor checking for inner nul bytes.
impl From for CString
fn from(s: &CStr) -> CStringConverts a
&[CStr]into aCStringby copying the contents into a new allocation.
impl From for CString
fn from(s: Box<CStr>) -> CStringConverts a
[Box]<[CStr]>into aCStringwithout copying or allocating.
impl FromStr for CString
fn from_str(s: &str) -> Result<Self, <Self as >::Err>Converts a string
sinto aCString.This method is equivalent to
CString::new.
impl Hash for CString
fn hash<__H: $crate::hash::Hasher>(self: &Self, state: &mut __H)
impl Index for CString
fn index(self: &Self, _index: ops::RangeFull) -> &CStr
impl Ord for CString
fn cmp(self: &Self, other: &CString) -> $crate::cmp::Ordering
impl PartialEq for CString
fn eq(self: &Self, other: &CStr) -> boolfn ne(self: &Self, other: &CStr) -> bool
impl PartialEq for CString
fn eq(self: &Self, other: &Cow<'_, CStr>) -> boolfn ne(self: &Self, other: &Cow<'_, CStr>) -> bool
impl PartialEq for CString
fn eq(self: &Self, other: &CString) -> bool
impl PartialEq for CString
fn eq(self: &Self, other: &&CStr) -> boolfn ne(self: &Self, other: &&CStr) -> bool
impl PartialOrd for CString
fn partial_cmp(self: &Self, other: &CString) -> $crate::option::Option<$crate::cmp::Ordering>
impl RefUnwindSafe for CString
impl Send for CString
impl StructuralPartialEq for CString
impl Sync for CString
impl Unpin for CString
impl UnwindSafe for CString
impl<'a> From for CString
fn from(s: Cow<'a, CStr>) -> SelfConverts a
Cow<'a, CStr>into aCString, by copying the contents if they are borrowed.
impl<P, T> Receiver for CString
impl<T> Any for CString
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for CString
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for CString
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for CString
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for CString
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for CString
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, U> Into for CString
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for CString
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for CString
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>