mbox/
lib.rs

1//! `mbox`: `malloc`-based box
2//! ==========================
3//!
4//! This crate provides structures that wrap pointers returned from `malloc` as a Box, and
5//! automatically `free` them on drop. These types allow you to interact with pointers and
6//! null-terminated strings and arrays in a Rusty style.
7//!
8//! ## Examples
9//!
10//! ```rust
11//! extern crate libc;
12//! extern crate mbox;
13//!
14//! use libc::{c_char, malloc, strcpy};
15//! use mbox::MString;
16//!
17//! // Assume we have a C function that returns a malloc'ed string.
18//! unsafe extern "C" fn create_str() -> *mut c_char {
19//!     let ptr = malloc(12) as *mut c_char;
20//!     strcpy(ptr, b"Hello world\0".as_ptr() as *const c_char);
21//!     ptr
22//! }
23//!
24//! fn main() {
25//!     // we wrap the null-terminated string into an MString.
26//!     let string = unsafe { MString::from_raw_unchecked(create_str()) };
27//!
28//!     // check the content is expected.
29//!     assert_eq!(&*string, "Hello world");
30//!
31//!     // the string will be dropped by `free` after the code is done.
32//! }
33//! ```
34//!
35//! > Note: This crate does not support Windows in general.
36//! >
37//! > Pointers in Rust are required to be aligned to be sound. However, there is no API on
38//! > Windows that are both compatible with `free()` and supports aligned-malloc.
39//! >
40//! > Because the primary purpose of this crate is interoperability with C code working
41//! > with `malloc()`, it is impossible for us to switch to the safe variant like
42//! > [`_aligned_malloc()`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc)
43//! > (which requires [`_aligned_free()`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-free)).
44//! >
45//! > On Windows, trying to use `MBox<T>` or `MArray<T>` with `T`'s alignment not equal to 1
46//! > will not compile.
47//! >
48//! > ```rust,compile_fail
49//! > # #[cfg(not(windows))] { _ };
50//! >
51//! > use mbox::MBox;
52//! > let value = MBox::new(1_u64); // will not compile,
53//! > ```
54//!
55//!
56//! ## Installation
57//!
58//! Add this to your Cargo.toml:
59//!
60//! ```toml
61//! [dependencies]
62//! mbox = "0.7"
63//! ```
64//!
65//! ## Usage
66//!
67//! This crate provides three main types, all of which uses the system's `malloc`/`free` as the
68//! allocator.
69//!
70//! * `MBox<T>` — Similar to `Box<T>`.
71//! * `MString` — Similar to `std::ffi::CString`.
72//! * `MArray<T>` — A null-terminated array, which can be used to represent e.g. array of C strings
73//!   terminated by a null pointer.
74//!
75//! ### `#![no_std]`
76//!
77//! You may compile `mbox` and disable the `std` feature to not link to `std` (it will still link to
78//! `core`.
79//!
80//! ```toml
81//! [dependencies]
82//! mbox = { version = "0.7", default-features = false }
83//! ```
84//!
85//! When `#![no_std]` is activated, you cannot convert an `MString` into a `std::ffi::CStr`, as the
86//! type simply does not exist 🙂.
87//!
88//! ### Nightly
89//!
90//! To use nightly-channel features (if you need support for custom dynamic-sized types), enable the
91//! `nightly` feature:
92//!
93//! ```toml
94//! [dependencies]
95//! mbox = { version = "0.7", features = ["nightly"] }
96//! ```
97//!
98//! ## Migrating from other crates
99//!
100//! Note that `MBox` does not support custom allocator. If the type requires custom allocation,
101//! `MBox` cannot serve you.
102//!
103//! * [`malloc_buf`](https://crates.io/crates/malloc_buf) — `Malloc<T>` is equivalent to `MBox<T>`.
104//!   Note however that `MBox<[T]>::from_raw_parts` will not allow null, 0-length buffers; use a
105//!   dangling pointer instead.
106//!
107//! * [`cbox`](https://crates.io/crates/cbox) — When not using a custom `DisposeRef`, the
108//!   `CSemiBox<'static, T>` type is equivalent to `MBox<T>`, and `CBox<T>` is equivalent to
109//!   `&'static T`.
110//!
111//! * [`c_vec`](https://crates.io/crates/c_vec) — When using `free` as the destructor, `CVec<T>` is
112//!   equivalent to `MBox<[T]>` and `CSlice<T>` as `[T]`.
113//!
114//! * [`malloced`](https://crates.io/crates/malloced) — `Malloced<T>` is equivalent to `MBox<T>`.
115//!   Note however that `mbox` depends on `libc` (more stable, but also longer build-time) and
116//!   doesn't support `dyn Any` downcasting.
117//!
118//! * [`malloc-array`](https://crates.io/crates/malloc-array) — `HeapArray<T>` is similar to
119//!   `MBox<T>`, but this crate focuses more on raw memory management.
120
121#![cfg_attr(
122    feature = "nightly",
123    feature(min_specialization, unsize, coerce_unsized)
124)]
125#![cfg_attr(not(feature = "std"), no_std)]
126
127#[cfg(not(feature = "std"))]
128extern crate core as std;
129extern crate libc;
130#[cfg(feature = "stable_deref_trait")]
131extern crate stable_deref_trait;
132
133pub mod free;
134mod internal;
135pub mod mbox;
136pub mod sentinel;
137
138pub use self::mbox::MBox;
139pub use self::sentinel::{MArray, MString};