diff --git a/rclrs/Cargo.toml b/rclrs/Cargo.toml index 00a9c09b1..50c9c3334 100644 --- a/rclrs/Cargo.toml +++ b/rclrs/Cargo.toml @@ -14,8 +14,6 @@ path = "src/lib.rs" # Please keep the list of dependencies alphabetically sorted, # and also state why each dependency is needed. [dependencies] -# Needed for FFI -libc = "0.2.43" # Needed for the Message trait, among others rosidl_runtime_rs = "0.3" # Needed for clients diff --git a/rclrs/src/arguments.rs b/rclrs/src/arguments.rs index 81c23420a..c091bf759 100644 --- a/rclrs/src/arguments.rs +++ b/rclrs/src/arguments.rs @@ -1,9 +1,8 @@ use std::ffi::CString; use std::os::raw::c_char; +use std::os::raw::c_void; use std::ptr::null_mut; -use libc::c_void; - use crate::error::*; use crate::rcl_bindings::*; diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index 323c3623b..cc0ecc665 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -3,10 +3,10 @@ mod graph; use std::cmp::PartialEq; use std::ffi::CStr; use std::fmt; +use std::os::raw::c_char; use std::sync::{Arc, Mutex, Weak}; use std::vec::Vec; -use libc::c_char; use rosidl_runtime_rs::Message; pub use self::builder::*; diff --git a/rclrs/src/parameter/override_map.rs b/rclrs/src/parameter/override_map.rs index 3311e6c76..72c3e70c4 100644 --- a/rclrs/src/parameter/override_map.rs +++ b/rclrs/src/parameter/override_map.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use std::ffi::CStr; - -use libc::c_char; +use std::os::raw::c_char; use crate::rcl_bindings::*; use crate::{ParameterValue, RclrsError, ToResult}; diff --git a/rosidl_generator_rs/resource/Cargo.toml.em b/rosidl_generator_rs/resource/Cargo.toml.em index 4c730bf95..110d2c41d 100644 --- a/rosidl_generator_rs/resource/Cargo.toml.em +++ b/rosidl_generator_rs/resource/Cargo.toml.em @@ -4,7 +4,6 @@ version = "@(package_version)" edition = "2021" [dependencies] -libc = "0.2" rosidl_runtime_rs = "0.3" serde = { version = "1", optional = true, features = ["derive"] } @[for dep in dependency_packages]@ diff --git a/rosidl_generator_rs/resource/msg_rmw.rs.em b/rosidl_generator_rs/resource/msg_rmw.rs.em index 24d416d01..b85061815 100644 --- a/rosidl_generator_rs/resource/msg_rmw.rs.em +++ b/rosidl_generator_rs/resource/msg_rmw.rs.em @@ -19,14 +19,15 @@ type_name = msg_spec.structure.namespaced_type.name #[link(name = "@(package_name)__rosidl_typesupport_c")] extern "C" { - fn rosidl_typesupport_c__get_message_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> libc::uintptr_t; + fn rosidl_typesupport_c__get_message_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> *const std::os::raw::c_void; } #[link(name = "@(package_name)__rosidl_generator_c")] extern "C" { fn @(package_name)__@(subfolder)__@(type_name)__init(msg: *mut @(type_name)) -> bool; - fn @(package_name)__@(subfolder)__@(type_name)__Sequence__init(seq: *mut rosidl_runtime_rs::Sequence<@(type_name)>, size: libc::size_t) -> bool; + fn @(package_name)__@(subfolder)__@(type_name)__Sequence__init(seq: *mut rosidl_runtime_rs::Sequence<@(type_name)>, size: usize) -> bool; fn @(package_name)__@(subfolder)__@(type_name)__Sequence__fini(seq: *mut rosidl_runtime_rs::Sequence<@(type_name)>); + fn @(package_name)__@(subfolder)__@(type_name)__Sequence__copy(in_seq: &rosidl_runtime_rs::Sequence<@(type_name)>, out_seq: *mut rosidl_runtime_rs::Sequence<@(type_name)>) -> bool; } @# Drop is not needed, since the default drop glue does the same as fini here: @@ -80,18 +81,17 @@ impl Default for @(type_name) { } impl rosidl_runtime_rs::SequenceAlloc for @(type_name) { - fn sequence_init(seq: &mut rosidl_runtime_rs::Sequence, size: libc::size_t) -> bool { - // SAFETY: This is safe since a the point is guaranteed to be valid/initialized. + fn sequence_init(seq: &mut rosidl_runtime_rs::Sequence, size: usize) -> bool { + // SAFETY: This is safe since the pointer is guaranteed to be valid/initialized. unsafe { @(package_name)__@(subfolder)__@(type_name)__Sequence__init(seq as *mut _, size) } } fn sequence_fini(seq: &mut rosidl_runtime_rs::Sequence) { - // SAFETY: This is safe since a the point is guaranteed to be valid/initialized. + // SAFETY: This is safe since the pointer is guaranteed to be valid/initialized. unsafe { @(package_name)__@(subfolder)__@(type_name)__Sequence__fini(seq as *mut _) } } fn sequence_copy(in_seq: &rosidl_runtime_rs::Sequence, out_seq: &mut rosidl_runtime_rs::Sequence) -> bool { - out_seq.resize_to_at_least(in_seq.len()); - out_seq.clone_from_slice(in_seq.as_slice()); - true + // SAFETY: This is safe since the pointer is guaranteed to be valid/initialized. + unsafe { @(package_name)__@(subfolder)__@(type_name)__Sequence__copy(in_seq, out_seq as *mut _) } } } @@ -103,7 +103,7 @@ impl rosidl_runtime_rs::Message for @(type_name) { impl rosidl_runtime_rs::RmwMessage for @(type_name) where Self: Sized { const TYPE_NAME: &'static str = "@(package_name)/@(subfolder)/@(type_name)"; - fn get_type_support() -> libc::uintptr_t { + fn get_type_support() -> *const std::os::raw::c_void { // SAFETY: No preconditions for this function. unsafe { rosidl_typesupport_c__get_message_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() } } diff --git a/rosidl_generator_rs/resource/srv.rs.em b/rosidl_generator_rs/resource/srv.rs.em index 925b8cdd3..31cabc768 100644 --- a/rosidl_generator_rs/resource/srv.rs.em +++ b/rosidl_generator_rs/resource/srv.rs.em @@ -24,7 +24,7 @@ type_name = srv_spec.namespaced_type.name #[link(name = "@(package_name)__rosidl_typesupport_c")] extern "C" { - fn rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> libc::uintptr_t; + fn rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> *const std::os::raw::c_void; } // Corresponds to @(package_name)__@(subfolder)__@(type_name) @@ -34,7 +34,7 @@ impl rosidl_runtime_rs::Service for @(type_name) { type Request = crate::@(subfolder)::@(type_name)_Request; type Response = crate::@(subfolder)::@(type_name)_Response; - fn get_type_support() -> libc::uintptr_t { + fn get_type_support() -> *const std::os::raw::c_void { // SAFETY: No preconditions for this function. unsafe { rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() } } @@ -61,7 +61,7 @@ type_name = srv_spec.namespaced_type.name #[link(name = "@(package_name)__rosidl_typesupport_c")] extern "C" { - fn rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> libc::uintptr_t; + fn rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> *const std::os::raw::c_void; } // Corresponds to @(package_name)__@(subfolder)__@(type_name) @@ -71,7 +71,7 @@ type_name = srv_spec.namespaced_type.name type Request = crate::@(subfolder)::rmw::@(type_name)_Request; type Response = crate::@(subfolder)::rmw::@(type_name)_Response; - fn get_type_support() -> libc::uintptr_t { + fn get_type_support() -> *const std::os::raw::c_void { // SAFETY: No preconditions for this function. unsafe { rosidl_typesupport_c__get_service_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() } } diff --git a/rosidl_runtime_rs/Cargo.toml b/rosidl_runtime_rs/Cargo.toml index 1897650fe..cb71252f9 100644 --- a/rosidl_runtime_rs/Cargo.toml +++ b/rosidl_runtime_rs/Cargo.toml @@ -13,8 +13,6 @@ path = "src/lib.rs" # Please keep the list of dependencies alphabetically sorted, # and also state why each dependency is needed. [dependencies] -# Needed for FFI -libc = "0.2" # Optional dependency for making it possible to convert messages to and from # formats such as JSON, YAML, Pickle, etc. serde = { version = "1", optional = true } @@ -24,4 +22,3 @@ serde = { version = "1", optional = true } quickcheck = "1" # Needed for testing serde support serde_json = "1" - diff --git a/rosidl_runtime_rs/src/sequence.rs b/rosidl_runtime_rs/src/sequence.rs index 64b5892b9..3ac2127b8 100644 --- a/rosidl_runtime_rs/src/sequence.rs +++ b/rosidl_runtime_rs/src/sequence.rs @@ -37,8 +37,8 @@ use crate::traits::SequenceAlloc; #[repr(C)] pub struct Sequence { data: *mut T, - size: libc::size_t, - capacity: libc::size_t, + size: usize, + capacity: usize, } /// A bounded sequence. @@ -274,30 +274,6 @@ where } } -impl Sequence { - /// Internal function for the sequence_copy impl. To be removed when rosidl#650 is backported and released. - pub fn resize_to_at_least(&mut self, len: usize) { - let allocation_size = std::mem::size_of::() * len; - if self.capacity < len { - // SAFETY: The memory in self.data is owned by C. - let data = unsafe { libc::realloc(self.data as *mut _, allocation_size) } as *mut T; - if data.is_null() { - panic!("realloc failed"); - } - // Initialize the new memory - for i in self.capacity..len { - // SAFETY: i is in bounds, and write() is appropriate for initializing uninitialized memory - unsafe { - data.add(i).write(T::default()); - } - } - self.data = data; - self.size = len; - self.capacity = len; - } - } -} - // ========================= impl for BoundedSequence ========================= impl Debug for BoundedSequence { @@ -518,12 +494,16 @@ macro_rules! impl_sequence_alloc_for_primitive_type { ($rust_type:ty, $init_func:ident, $fini_func:ident, $copy_func:ident) => { #[link(name = "rosidl_runtime_c")] extern "C" { - fn $init_func(seq: *mut Sequence<$rust_type>, size: libc::size_t) -> bool; + fn $init_func(seq: *mut Sequence<$rust_type>, size: usize) -> bool; fn $fini_func(seq: *mut Sequence<$rust_type>); + fn $copy_func( + in_seq: *const Sequence<$rust_type>, + out_seq: *mut Sequence<$rust_type>, + ) -> bool; } impl SequenceAlloc for $rust_type { - fn sequence_init(seq: &mut Sequence, size: libc::size_t) -> bool { + fn sequence_init(seq: &mut Sequence, size: usize) -> bool { // SAFETY: There are no special preconditions to the sequence_init function. unsafe { // This allocates space and sets seq.size and seq.capacity to size @@ -538,26 +518,8 @@ macro_rules! impl_sequence_alloc_for_primitive_type { unsafe { $fini_func(seq as *mut _) } } fn sequence_copy(in_seq: &Sequence, out_seq: &mut Sequence) -> bool { - let allocation_size = std::mem::size_of::() * in_seq.size; - if out_seq.capacity < in_seq.size { - // SAFETY: The memory in out_seq.data is owned by C. - let data = unsafe { libc::realloc(out_seq.data as *mut _, allocation_size) }; - if data.is_null() { - return false; - } - out_seq.data = data as *mut _; - out_seq.capacity = in_seq.size; - } - // SAFETY: The memory areas don't overlap. - unsafe { - libc::memcpy( - out_seq.data as *mut _, - in_seq.data as *const _, - allocation_size, - ); - } - out_seq.size = in_seq.size; - true + // SAFETY: There are no special preconditions to the sequence_copy function. + unsafe { $copy_func(in_seq as *const _, out_seq as *mut _) } } } }; diff --git a/rosidl_runtime_rs/src/string.rs b/rosidl_runtime_rs/src/string.rs index 305062a14..201889a95 100644 --- a/rosidl_runtime_rs/src/string.rs +++ b/rosidl_runtime_rs/src/string.rs @@ -29,9 +29,9 @@ use crate::traits::SequenceAlloc; pub struct String { /// Dynamic memory in this type is allocated and deallocated by C, but this is a detail that is managed by /// the relevant functions and trait impls. - data: *mut libc::c_char, - size: libc::size_t, - capacity: libc::size_t, + data: *mut std::os::raw::c_char, + size: usize, + capacity: usize, } /// A zero-terminated string of 16-bit characters. @@ -50,9 +50,9 @@ pub struct String { /// ``` #[repr(C)] pub struct WString { - data: *mut libc::c_ushort, - size: libc::size_t, - capacity: libc::size_t, + data: *mut std::os::raw::c_ushort, + size: usize, + capacity: usize, } /// A zero-terminated string of 8-bit characters with a length limit. @@ -117,9 +117,13 @@ macro_rules! string_impl { extern "C" { fn $init(s: *mut $string) -> bool; fn $fini(s: *mut $string); - fn $assignn(s: *mut $string, value: *const $char_type, n: libc::size_t) -> bool; - fn $sequence_init(seq: *mut Sequence<$string>, size: libc::size_t) -> bool; + fn $assignn(s: *mut $string, value: *const $char_type, n: usize) -> bool; + fn $sequence_init(seq: *mut Sequence<$string>, size: usize) -> bool; fn $sequence_fini(seq: *mut Sequence<$string>); + fn $sequence_copy( + in_seq: *const Sequence<$string>, + out_seq: *mut Sequence<$string>, + ) -> bool; } impl Default for $string { @@ -226,7 +230,7 @@ macro_rules! string_impl { unsafe impl Sync for $string {} impl SequenceAlloc for $string { - fn sequence_init(seq: &mut Sequence, size: libc::size_t) -> bool { + fn sequence_init(seq: &mut Sequence, size: usize) -> bool { // SAFETY: There are no special preconditions to the sequence_init function. unsafe { $sequence_init(seq as *mut _, size) } } @@ -235,9 +239,8 @@ macro_rules! string_impl { unsafe { $sequence_fini(seq as *mut _) } } fn sequence_copy(in_seq: &Sequence, out_seq: &mut Sequence) -> bool { - out_seq.resize_to_at_least(in_seq.len()); - out_seq.clone_from_slice(in_seq.as_slice()); - true + // SAFETY: There are no special preconditions to the sequence_copy function. + unsafe { $sequence_copy(in_seq as *const _, out_seq as *mut _) } } } }; @@ -245,7 +248,7 @@ macro_rules! string_impl { string_impl!( String, - libc::c_char, + std::os::raw::c_char, u8, from_utf8_lossy, rosidl_runtime_c__String__init, @@ -257,7 +260,7 @@ string_impl!( ); string_impl!( WString, - libc::c_ushort, + std::os::raw::c_ushort, u16, from_utf16_lossy, rosidl_runtime_c__U16String__init, @@ -330,7 +333,7 @@ impl Debug for BoundedString { } impl Deref for BoundedString { - type Target = [libc::c_char]; + type Target = [std::os::raw::c_char]; fn deref(&self) -> &Self::Target { self.inner.deref() } @@ -349,7 +352,7 @@ impl Display for BoundedString { } impl SequenceAlloc for BoundedString { - fn sequence_init(seq: &mut Sequence, size: libc::size_t) -> bool { + fn sequence_init(seq: &mut Sequence, size: usize) -> bool { // SAFETY: There are no special preconditions to the rosidl_runtime_c__String__Sequence__init function. unsafe { rosidl_runtime_c__String__Sequence__init(seq as *mut Sequence as *mut _, size) @@ -415,7 +418,7 @@ impl Display for BoundedWString { } impl SequenceAlloc for BoundedWString { - fn sequence_init(seq: &mut Sequence, size: libc::size_t) -> bool { + fn sequence_init(seq: &mut Sequence, size: usize) -> bool { // SAFETY: There are no special preconditions to the rosidl_runtime_c__U16String__Sequence__init function. unsafe { rosidl_runtime_c__U16String__Sequence__init(seq as *mut Sequence as *mut _, size) diff --git a/rosidl_runtime_rs/src/traits.rs b/rosidl_runtime_rs/src/traits.rs index 4737bd1aa..d468a42d5 100644 --- a/rosidl_runtime_rs/src/traits.rs +++ b/rosidl_runtime_rs/src/traits.rs @@ -24,7 +24,7 @@ use std::fmt::Debug; /// User code never needs to call these trait methods, much less implement this trait. pub trait SequenceAlloc: Sized { /// Wraps the corresponding init function generated by `rosidl_generator_c`. - fn sequence_init(seq: &mut crate::Sequence, size: libc::size_t) -> bool; + fn sequence_init(seq: &mut crate::Sequence, size: usize) -> bool; /// Wraps the corresponding fini function generated by `rosidl_generator_c`. fn sequence_fini(seq: &mut crate::Sequence); /// Wraps the corresponding copy function generated by `rosidl_generator_c`. @@ -42,7 +42,7 @@ pub trait RmwMessage: Clone + Debug + Default + Send + Sync + Message { const TYPE_NAME: &'static str; /// Get a pointer to the correct `rosidl_message_type_support_t` structure. - fn get_type_support() -> libc::uintptr_t; + fn get_type_support() -> *const std::os::raw::c_void; } /// Trait for types that can be used in a `rclrs::Subscription` and a `rclrs::Publisher`. @@ -158,5 +158,5 @@ pub trait Service: 'static { type Response: Message; /// Get a pointer to the correct `rosidl_service_type_support_t` structure. - fn get_type_support() -> libc::uintptr_t; + fn get_type_support() -> *const std::os::raw::c_void; }