From your original post it would seem you are more concerned about safety than speed – rightfully. Did you measure that copying a flat byte buffer is indeed what slows your code down? memcpy() is incredibly fast these days.
Here it is:
use std::isize;
use std::slice;
use std::ops::{ Deref, DerefMut };
struct CBuffer {
ptr: *mut u8,
len: usize,
}
impl CBuffer {
/// Constructor. Transfers ownership of `ptr`.
pub unsafe fn from_owning(ptr: *mut u8, len: usize) -> Option<Self> {
if ptr.is_null() || len > isize::MAX as usize {
// slices are not allowed to be backed by a null pointer
// or be longer than `isize::MAX`. Alignment is irrelevant for `u8`.
None
} else {
Some(CBuffer { ptr, len })
}
}
}
impl Drop for CBuffer {
/// Destructor.
fn drop(&mut self) {
unsafe {
libc::free(self.ptr);
// for example. Might need custom deallocation.
}
}
}
impl Deref for CBuffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
unsafe {
slice::from_raw_parts(self.buf as *const u8, self.len)
}
}
}
impl DerefMut for CBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
slice::from_raw_parts_mut(self.ptr, self.len)
}
}
}
A slice &[T] is explicitly convertible or implicitly coercible to a raw slice *const [T] which in turn is explicitly convertible to a pointer-to-first-element. There's also the convenience method <[T]>::as_ptr(). So you can easily pass a slice to a C function like this:
let slice: &[u8] = &[1, 2, 3, 4];
unsafe {
c_function_taking_ptr_and_length(slice.as_ptr(), slice.len());
}
When you pass to a C function a slice pointing into memory that is owned by a Rust data structure, then you must not free it from C.
If you want to transfer ownership, you need to convert your data structure into a "forgetful" raw pointer (cf. Box::into_raw() or Vec::into_raw_parts()), use that in C, and when it's time to destroy the value, you need to pass it back to Rust, convert it back to an owning data type (cf. Box::from_raw() and Vec::from_raw_parts()), and let Rust free it. You can always write an extern "C" function in Rust for this purpose.