15 releases

0.7.2 Apr 5, 2021
0.7.1-obsolete Dec 20, 2017
0.7.0 Apr 4, 2015
0.6.2 Mar 27, 2015

#3 in #nul

Download history 6/week @ 2023-12-11 1/week @ 2024-01-22 4/week @ 2024-01-29 16/week @ 2024-02-12 75/week @ 2024-02-19 37/week @ 2024-02-26 7/week @ 2024-03-04 22/week @ 2024-03-11 13/week @ 2024-03-18 22/week @ 2024-03-25

69 downloads per month

Apache-2.0/MIT

18KB
331 lines

C string helpers for Rust

Maintenance Status

Deprecation notice

This crate is no longer maintained. If you were using it only for the c_str! macro, consider switching to c_str_macro or byte-strings.


lib.rs:

This library provides helpers for creating and managing null-terminated strings for use with FFI calls. Most C APIs require that the string being passed to them is null-terminated and many of them allocate and return null-terminated strings, but Rust's built-in string types are not null terminated.

The other problem with translating Rust strings to C strings is that Rust strings can validly contain a NUL byte in the middle of the string (0 is a valid Unicode codepoint). This means that not all Rust strings can actually be translated to C strings.

Managing foreign-allocated C strings

An allocated C string is managed through the type OwnedCString. Values of this type "own" an internal buffer of characters and will call a destructor when the value is dropped.

Creation of a C string

The type CStrBuf is used to adapt string data from Rust for calling C functions that expect a null-terminated string. The conversion constructors of CStrBuf provide various ways to produce C strings, but the conversions can fail due to some of the limitations explained above.

Borrowed C strings

Both OwnedCString and CStrBuf dereference to std::ffi::CStr, an unsized type that asserts the C string requirements when passed or returned by reference. &CStr can be used to encapsulate FFI functions under a safe facade.

An example of creating and using a C string would be:


extern crate c_string;
extern crate libc;

use c_string::CStrBuf;
use std::ffi::CStr;

fn safe_puts(s: &CStr) {
    unsafe { libc::puts(s.as_ptr()) };
}

fn main() {
    let my_string = "Hello, world!";

    // Allocate the C string with an explicit local that owns the string.
    // The string will be deallocated when `my_c_string` goes out of scope.
    let my_c_string = match CStrBuf::from_str(my_string) {
            Ok(s) => s,
            Err(e) => panic!(e)
        };

    safe_puts(&my_c_string);
}

Dependencies

~42KB