1#[cfg(feature = "cuda")]
16pub mod cuda;
17
18use std::ffi::CStr;
19
20use anyhow::{anyhow, Result};
21
22#[repr(C)]
23pub struct CppError {
24 msg: *const std::os::raw::c_char,
25}
26
27impl Drop for CppError {
28 fn drop(&mut self) {
29 extern "C" {
30 fn free(str: *const std::os::raw::c_char);
31 }
32 unsafe { free(self.msg) };
33 }
34}
35
36impl Default for CppError {
37 fn default() -> Self {
38 Self {
39 msg: std::ptr::null(),
40 }
41 }
42}
43
44impl CppError {
45 pub fn unwrap(self) {
46 if !self.msg.is_null() {
47 let c_str = unsafe { std::ffi::CStr::from_ptr(self.msg) };
48 panic!("{}", c_str.to_str().unwrap_or("unknown error"));
49 }
50 }
51}
52
53pub fn ffi_wrap<F>(mut inner: F) -> Result<()>
54where
55 F: FnMut() -> *const std::os::raw::c_char,
56{
57 extern "C" {
58 fn free(str: *const std::os::raw::c_char);
59 }
60
61 let c_ptr = inner();
62 if c_ptr.is_null() {
63 Ok(())
64 } else {
65 let what = unsafe {
66 let msg = CStr::from_ptr(c_ptr)
67 .to_str()
68 .unwrap_or("Invalid error msg pointer")
69 .to_string();
70 free(c_ptr);
71 msg
72 };
73 Err(anyhow!(what))
74 }
75}