31 lines
1.0 KiB
Rust
31 lines
1.0 KiB
Rust
use std::ffi::{CStr, CString};
|
|
use std::os::raw::c_char;
|
|
|
|
// Symbols every module must export with `extern "C"` and `#[no_mangle]`.
|
|
// Signature: fn module_name() -> *const c_char
|
|
// Signature: fn module_invoke(op: *const c_char, payload: *const c_char) -> *mut c_char
|
|
pub const SYMBOL_NAME: &str = "module_name";
|
|
pub const SYMBOL_INVOKE: &str = "module_invoke";
|
|
|
|
// Helper to convert C char* to &str
|
|
pub unsafe fn cstr_to_str<'a>(ptr: *const c_char) -> anyhow::Result<&'a str> {
|
|
if ptr.is_null() {
|
|
anyhow::bail!("null pointer");
|
|
}
|
|
Ok(CStr::from_ptr(ptr).to_str()?)
|
|
}
|
|
|
|
// Helper to allocate a CString for return across FFI boundary (module side)
|
|
pub fn string_to_cstring_ptr(s: String) -> *mut c_char {
|
|
CString::new(s).unwrap().into_raw()
|
|
}
|
|
|
|
// Helper to take back ownership of a CString (host side), then free by letting CString drop
|
|
pub unsafe fn take_cstring(ptr: *mut c_char) -> anyhow::Result<String> {
|
|
if ptr.is_null() {
|
|
anyhow::bail!("null pointer");
|
|
}
|
|
let s = CString::from_raw(ptr);
|
|
Ok(s.into_string()?)
|
|
}
|