ffi: wrap unsafe FFI functions in safe wrappers

This commit is contained in:
2025-11-12 15:14:20 +01:00
parent 2802f7659f
commit c1488507f2
+38 -59
View File
@@ -1,29 +1,12 @@
/* mod ffi_point {
SPDX-License-Identifier: AGPL-3.0-or-later use std::os::raw::c_double;
Copyright (C) 2025 Erick Ahmed
*/
use std::os::raw::c_double; #[repr(C)]
pub(crate) struct PointShape {
_private: [u8; 0],
}
// FFI bindings unsafe extern "C" {
#[repr(C)]
pub struct PointShape {
_private: [u8; 0],
}
extern "C" {
pub fn make_point(x: c_double, y: c_double, z: c_double) -> *mut PointShape;
pub fn coord_point(
shape: *const PointShape,
x: *mut c_double,
y: *mut c_double,
z: *mut c_double,
);
pub fn delete_point(shape: *mut PointShape);
}
extern "C" {
fn make_point(x: c_double, y: c_double, z: c_double) -> *mut PointShape; fn make_point(x: c_double, y: c_double, z: c_double) -> *mut PointShape;
fn coord_point( fn coord_point(
shape: *const PointShape, shape: *const PointShape,
@@ -34,47 +17,43 @@ extern "C" {
fn delete_point(shape: *mut PointShape); fn delete_point(shape: *mut PointShape);
} }
pub struct Point { // Safe wrapper
ptr: *mut PointShape,
}
impl Point { pub struct Point {
pub fn new(x: f64, y: f64, z: f64) -> Self { ptr: *mut PointShape,
unsafe { }
let ptr = make_point(x, y, z);
if ptr.is_null() { impl Point {
panic!("Error: null pointer"); pub fn new(x: f64, y: f64, z: f64) -> Result<Self, &'static str> {
unsafe {
let ptr = make_point(x, y, z);
if ptr.is_null() {
Err("Error: null pointer returned")
} else {
Ok(Point { ptr })
}
}
}
pub fn coordinates(&self) -> (f64, f64, f64) {
unsafe {
let mut x = 0.0;
let mut y = 0.0;
let mut z = 0.0;
coord_point(self.ptr, &mut x, &mut y, &mut z);
(x, y, z)
} }
Self { ptr }
} }
} }
pub fn coordinates(&self) -> (f64, f64, f64) { impl Drop for Point {
unsafe { fn drop(&mut self) {
let mut x = 0.0; unsafe {
let mut y = 0.0; delete_point(self.ptr);
let mut z = 0.0; }
coord_point(self.ptr, &mut x, &mut y, &mut z);
(x, y, z)
} }
} }
}
impl Drop for Point { unsafe impl Send for Point {}
fn drop(&mut self) { unsafe impl Sync for Point {}
unsafe {
delete_point(self.ptr);
}
}
} }
impl Clone for Point {
fn clone(&self) -> Self {
let (x, y, z) = self.coordinates();
Self::new(x, y, z)
}
}
unsafe impl Send for Point {}
unsafe impl Sync for Point {}