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
+21 -42
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 {
// FFI bindings
#[repr(C)]
pub struct PointShape {
_private: [u8; 0], _private: [u8; 0],
} }
extern "C" { unsafe 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,18 +17,21 @@ 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,
}
impl Point {
pub fn new(x: f64, y: f64, z: f64) -> Result<Self, &'static str> {
unsafe { unsafe {
let ptr = make_point(x, y, z); let ptr = make_point(x, y, z);
if ptr.is_null() { if ptr.is_null() {
panic!("Error: null pointer"); Err("Error: null pointer returned")
} else {
Ok(Point { ptr })
} }
Self { ptr }
} }
} }
@@ -54,27 +40,20 @@ impl Point {
let mut x = 0.0; let mut x = 0.0;
let mut y = 0.0; let mut y = 0.0;
let mut z = 0.0; let mut z = 0.0;
coord_point(self.ptr, &mut x, &mut y, &mut z); coord_point(self.ptr, &mut x, &mut y, &mut z);
(x, y, z) (x, y, z)
} }
} }
} }
impl Drop for Point { impl Drop for Point {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
delete_point(self.ptr); 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 Send for Point {}
unsafe impl Sync for Point {} unsafe impl Sync for Point {}
}