diff options
| author | Jake Goulding <jake.goulding@gmail.com> | 2015-05-25 12:37:45 -0400 |
|---|---|---|
| committer | Jake Goulding <jake.goulding@gmail.com> | 2015-06-05 22:27:09 -0400 |
| commit | e20a6dbeed095427e5d5487844f65e7eb1599651 (patch) | |
| tree | abd0a78c5af854819398e5e33576b2752961dbcc | |
| parent | 97294be30c8712a91060d0ce043adefb4f867db8 (diff) | |
| download | rust-e20a6dbeed095427e5d5487844f65e7eb1599651.tar.gz rust-e20a6dbeed095427e5d5487844f65e7eb1599651.zip | |
Add methods for handing CStrings back and forth to C
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 9bc9e7530dd..433bb335a80 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -11,7 +11,7 @@ #![unstable(feature = "std_misc")] use borrow::{Cow, ToOwned}; -use boxed::Box; +use boxed::{self, Box}; use clone::Clone; use convert::{Into, From}; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; @@ -202,6 +202,34 @@ impl CString { CString { inner: v.into_boxed_slice() } } + /// Retakes ownership of a CString that was transferred to C. + /// + /// The only appropriate argument is a pointer obtained by calling + /// `into_ptr`. The length of the string will be recalculated + /// using the pointer. + #[unstable(feature = "cstr_memory", reason = "recently added")] + pub unsafe fn from_ptr(ptr: *const libc::c_char) -> CString { + let len = libc::strlen(ptr) + 1; // Including the NUL byte + let slice = slice::from_raw_parts(ptr, len as usize); + CString { inner: mem::transmute(slice) } + } + + /// Transfers ownership of the string to a C caller. + /// + /// The pointer must be returned to Rust and reconstituted using + /// `from_ptr` to be properly deallocated. Specifically, one + /// should *not* use the standard C `free` function to deallocate + /// this string. + /// + /// Failure to call `from_ptr` will lead to a memory leak. + #[unstable(feature = "cstr_memory", reason = "recently added")] + pub fn into_ptr(self) -> *const libc::c_char { + // It is important that the bytes be sized to fit - we need + // the capacity to be determinable from the string length, and + // shrinking to fit is the only way to be sure. + boxed::into_raw(self.inner) as *const libc::c_char + } + /// Returns the contents of this `CString` as a slice of bytes. /// /// The returned slice does **not** contain the trailing nul separator and |
