diff --git a/rclrs/src/dynamic_message/dynamic_publisher.rs b/rclrs/src/dynamic_message/dynamic_publisher.rs index af5ef5b22..fd2ed4ce0 100644 --- a/rclrs/src/dynamic_message/dynamic_publisher.rs +++ b/rclrs/src/dynamic_message/dynamic_publisher.rs @@ -125,9 +125,19 @@ impl DynamicPublisherState { } let rcl_publisher = &mut *self.handle.rcl_publisher.lock().unwrap(); unsafe { - // SAFETY: The message type is guaranteed to match the publisher type by the type system. + // SAFETY: Unlike `Publisher`, nothing here is enforced by the type system -- + // a `DynamicMessage`'s type is a runtime value. What guarantees the match is the + // `message_type` comparison at the top of this function. + // + // That comparison is by name (`MessageTypeName`), so it stands on the two type + // support libraries for a given package describing the same layout: the + // introspection one laid out `message.storage` (via `DynamicMessageMetadata`), + // while `rcl_publish` serialises those bytes through the `rosidl_typesupport_c` + // one. `DynamicPublisher::create` resolves both from the same package name, so + // they come from one install prefix. + // // The message does not need to be valid beyond the duration of this function call. - // The third argument is explictly allowed to be NULL. + // The third argument is explicitly allowed to be NULL. rcl_publish( rcl_publisher, message.storage.as_mut_ptr() as *mut _, diff --git a/rclrs/src/dynamic_message/dynamic_subscription.rs b/rclrs/src/dynamic_message/dynamic_subscription.rs index ddc3de290..cb8c1d94e 100644 --- a/rclrs/src/dynamic_message/dynamic_subscription.rs +++ b/rclrs/src/dynamic_message/dynamic_subscription.rs @@ -201,6 +201,12 @@ impl DynamicSubscriptionExecutable { // SAFETY: The first two pointers are valid/initialized, and do not need to be valid // beyond the function call. // The latter two pointers are explicitly allowed to be NULL. + // + // `rmw_message` points at storage laid out by the *introspection* type support + // (`self.metadata.create()`), while `rcl_take` writes it through the + // `rosidl_typesupport_c` one. Those must describe the same layout; + // `DynamicSubscription::create` resolves both from the same package name, so they + // come from one install prefix. rcl_take( rcl_subscription, rmw_message as *mut _,