//! Foreign function interface utilities. use crate::err::*; pub use std::{ffi::*, os::raw::*, ptr::{null, null_mut}}; /// Creates a C string from a literal. #[macro_export] macro_rules! c_str { ($s:expr) => { concat!($s, "\0").as_ptr() as $crate::ffi::NT }; } #[inline] pub const fn null_void() -> *const c_void {null()} #[inline] pub const fn null_mut_void() -> *mut c_void {null_mut()} impl CStringVec { /// Creates a new `CStringVec` from an iterator. #[inline] pub fn new_from_iter<'a, I>(it: I) -> ResultS where I: Iterator { let mut v = Self::default(); for st in it { v.push(CString::new(st)?); } Ok(v) } /// Pushes a new `CString`. #[inline] pub fn push(&mut self, st: CString) { self.cv.insert(self.cv.len() - 1, st.as_ptr()); self.sv.push(st); } /// Returns the FFI pointer. #[inline] pub fn as_ptr(&self) -> *const NT {self.cv.as_ptr()} /// Returns the FFI pointer mutably. #[inline] pub fn as_mut_ptr(&mut self) -> *mut NT {self.cv.as_mut_ptr()} } impl Default for CStringVec { /// Creates a new empty CStringVec. #[inline] fn default() -> Self {Self{sv: Vec::new(), cv: vec![null()]}} } /// An owned null-terminated string vector. #[derive(Debug)] pub struct CStringVec { sv: Vec, cv: Vec, } /// A null-terminated byte string pointer. pub type NT = *const c_char; // EOF