diff --git a/source/durandal/ffi.rs b/source/durandal/ffi.rs new file mode 100644 index 0000000..5d61932 --- /dev/null +++ b/source/durandal/ffi.rs @@ -0,0 +1,61 @@ +//! Foreign function interface utilities. + +use crate::durandal::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 *const c_char}; +} + +impl CStringVec +{ + /// Creates a new empty CStringVec. + pub fn new() -> Self + { + Self::default() + } + + /// Creates a new `CStringVec` from an iterator. + pub fn new_from_iter<'a, I: Iterator>(it: I) + -> ResultS + { + let mut v = Self::new(); + + for st in it { + v.push(CString::new(st)?); + } + + Ok(v) + } + + /// Pushes a new `CString`. + pub fn push(&mut self, st: CString) + { + self.cv.push(st.as_c_str().as_ptr()); + self.sv.push(st); + } + + /// Returns the FFI pointer. + pub fn as_ptr(&self) -> *const *const c_char + { + self.cv.as_ptr() + } + + /// Returns the FFI pointer mutably. + pub fn as_mut_ptr(&mut self) -> *mut *const c_char + { + self.cv.as_mut_ptr() + } +} + +/// An owned FFI-compatible string vector. +#[derive(Default)] +pub struct CStringVec +{ + sv: Vec, + cv: Vec<*const c_char>, +} + +// EOF diff --git a/source/durandal/mod.rs b/source/durandal/mod.rs index 8a3b530..a2b8adf 100644 --- a/source/durandal/mod.rs +++ b/source/durandal/mod.rs @@ -1,5 +1,7 @@ //! Library for utilities. +#[macro_use] +pub mod ffi; #[macro_use] pub mod err; #[macro_use]