From 9471a2086a143a31b65ede9e29c63974cf09cde1 Mon Sep 17 00:00:00 2001 From: mcb2003 Date: Sat, 12 Dec 2020 01:13:40 +0000 Subject: [PATCH] FFI: Create error handling code and LAST_ERROR static Any errors reported will cause the C API functions to return an error value (NULL or -1). The caller can then use: * const char* tts_get_error() to get a pointer to a string describing the error * void tts_clear_error() to deallocate any currently stored error message. --- src/ffi.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/ffi.rs b/src/ffi.rs index e69de29..5a2e286 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -0,0 +1,37 @@ +use libc::c_char; +use std::{ + cell::RefCell, + ffi::{CString, NulError}, + ptr, +}; + +thread_local! { + /// Stores the last reported error, so it can be retrieved at will from C + static LAST_ERROR: RefCell> = RefCell::new(None); +} + +fn set_last_error>>(err: E) -> Result<(), NulError> { + LAST_ERROR.with(|last| { + *last.borrow_mut() = Some(CString::new(err)?); + Ok(()) + }) +} + +/// Get the last reported error as a const C string (const char*) +/// This string will be valid until at least the next call to `tts_get_error`. +/// It is never called internally by the library. +#[no_mangle] +pub extern "C" fn tts_get_error() -> *const c_char { + LAST_ERROR.with(|err| match &*err.borrow() { + Some(e) => e.as_ptr(), + None => ptr::null(), + }) +} + +/// Deallocate the last reported error (if any). +#[no_mangle] +pub extern "C" fn tts_clear_error() { + LAST_ERROR.with(|err| { + *err.borrow_mut() = None; + }); +}