ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错
-
问题
/usr/include/boost/smart_ptr/make_shared_object.hpp: In instantiation of ‘class boost::detail::sp_ms_deleter<ros::Subscription>’: /usr/include/boost/smart_ptr/make_shared_object.hpp:254:21: required from ‘typename boost::detail::sp_if_not_array<T>::type boost::make_shared(Args&& ...) [with T = ros::Subscription; Args = {ros::Subscriber}; typename boost::detail::sp_if_not_array<T>::type = boost::shared_ptr<ros::Subscription>]’ /home/wd/cpp_proj/red_car_ros1/src/platooning_logic/src/trans_core.cpp:24:85: required from here /usr/include/boost/smart_ptr/make_shared_object.hpp:44:42: error: invalid application of ‘sizeof’ to incomplete type ‘ros::Subscription’ 44 | typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;背景
操作系统Ubuntu20,ROS1(noetic)。
涉及到的文件有以下两个,可以保证类成员函数A::localListCallBack和发布者类型platooning_msgs::PlatoonManagement是没有问题的。在工作空间目录下通过
catkin_make运行后出现以上错误,说ros::Subscription不是完整类型。以下是两个涉及到文件:
a.h#include <ros/ros.h> #include <boost/shared_ptr.hpp> class A{ public: boost::shared_ptr<ros::NodeHandle> nh = boost::make_shared<ros::NodeHandle>(); boost::shared_ptr<ros::Subscription> local_list_subscription; boost::shared_ptr<ros::Publisher> outer_publisher; }a.cpp
void A::func() { // 创建订阅者 local_list_subscription = boost::make_shared<ros::Subscription>( nh->subscribe("LocalMemberList", 1, &A::localListCallBack, this)); // 创建发布者 outer_publisher = boost::make_shared<ros::Publisher>(nh->advertise<platooning_msgs::PlatoonManagement>("OuterMemberList", 10)); }已尝试办法
刚开始并没有使用boost::shared_ptr的共享指针,使用的是std::shared_ptr,出现的问题基本相同,然后换成了boost::shared_ptr,也是一样的问题。
-
在您的代码中,您尝试使用
boost::shared_ptr来管理ros::Subscription和ros::Publisher对象,但遇到了编译错误。这是因为ros::Subscription和ros::Publisher并不是可以直接实例化的类型,它们是 ROS 框架内部通过特定方式管理的对象,通常通过ros::NodeHandle的成员函数subscribe和advertise返回的。在 ROS 中,
ros::NodeHandle::subscribe返回一个ros::Subscriber对象,而ros::NodeHandle::advertise返回一个ros::Publisher对象。这些对象实际上是封装了底层通信机制的句柄,并且它们的设计并不支持被boost::shared_ptr或std::shared_ptr直接管理。解决方案
-
直接使用
ros::Subscriber和ros::Publisher对象:
您不需要将ros::Subscriber和ros::Publisher封装到shared_ptr中。这些对象在 ROS 框架的生命周期内是有效的,只要ros::NodeHandle是活动的,它们就可以被安全使用。 -
修改类定义:
在类A中,直接使用ros::Subscriber和ros::Publisher类型的成员变量。
修改后的
a.h文件应该如下所示:#include <ros/ros.h> class A { public: ros::NodeHandle nh; ros::Subscriber local_list_subscription; ros::Publisher outer_publisher; void localListCallBack(const YourMessageTypeConstPtr& msg); // 确保这个函数声明匹配您的回调函数 void func(); };修改后的
a.cpp文件应该如下所示:#include "a.h" #include <platooning_msgs/PlatoonManagement.h> // 确保包含正确的消息头文件 void A::localListCallBack(const YourMessageTypeConstPtr& msg) { // 处理消息 } void A::func() { // 创建订阅者 local_list_subscription = nh.subscribe("LocalMemberList", 1, &A::localListCallBack, this); // 创建发布者 outer_publisher = nh.advertise<platooning_msgs::PlatoonManagement>("OuterMemberList", 10); }注意:
- 确保
YourMessageTypeConstPtr是正确的消息类型指针(例如,如果消息类型是platooning_msgs::SomeMessage,则应为platooning_msgs::SomeMessageConstPtr)。 - 确保所有必要的 ROS 消息和服务的头文件都已正确包含。
通过这种方式,您可以避免尝试将不适合的对象封装到
shared_ptr中,同时保持代码清晰和符合 ROS 的设计哲学。
以上为生成回答,仅供参考~
-
-
@小伊 、
如果在头文件a.h中写类成员对象
ros::Subscriber和ros::Publisher,在a.cpp中定义的时候,会出现error: field ‘local_list_subscription’ has incomplete type ‘ros::Subscription’ 82 | ros::Subscription local_list_subscription;的错误。刚开始就这样尝试的,因为出现这个错误,所以想着使用指针来处理。
-
在ROS(Robot Operating System)中,
ros::Subscriber和ros::Publisher是用于订阅和发布ROS消息的关键类。当你在头文件中声明这些类型的成员变量时,可能会遇到“incomplete type”错误,这通常是由于缺少相应的头文件包含或包含顺序不正确导致的。解决步骤
-
确保包含必要的ROS头文件:
在你的头文件a.h中,确保你已经包含了必要的ROS头文件来支持ros::Subscriber和ros::Publisher。通常,这些类定义在<ros/subscriber.h>和<ros/publisher.h>中,但更常见的做法是直接包含<ros/node_handle.h>,因为它会间接包含其他必要的头文件。#include <ros/node_handle.h> -
检查头文件包含顺序:
如果a.h依赖于其他自定义头文件,并且这些头文件中也可能引用了ROS的类型(或间接地依赖于ROS),确保a.h中的ROS头文件包含在这些依赖之前。 -
使用指针或引用:
虽然使用指针或引用不是解决“incomplete type”错误的直接方法(这通常是由于头文件缺失或包含顺序错误),但它们在某些情况下可以提供灵活性,特别是在涉及到复杂的依赖关系时。然而,首先你应该尝试解决根本的包含问题。如果你决定使用指针,确保在类定义中正确地声明和初始化它们。例如:
class MyClass { public: MyClass(ros::NodeHandle& nh); ~MyClass(); private: ros::Subscriber* local_list_subscription_; ros::Publisher* my_publisher_; }; MyClass::MyClass(ros::NodeHandle& nh) : local_list_subscription_(nh.subscribe("topic_name", 10, callbackFunction)), my_publisher_(nh.advertise<MessageType>("another_topic", 10)) {} MyClass::~MyClass() { delete local_list_subscription_; delete my_publisher_; }注意,使用裸指针需要小心管理内存(如上例中的
delete语句),或者使用智能指针(如std::unique_ptr或std::shared_ptr)来自动管理内存。 -
检查ROS环境和编译设置:
确保你的ROS环境已经正确设置,并且你的CMakeLists.txt文件已经包含了必要的find_package和target_link_libraries指令来链接ROS库。 -
重新编译:
在做了上述更改后,确保彻底清理你的构建环境(例如,使用catkin_make clean),然后重新编译你的项目。
通过遵循这些步骤,你应该能够解决关于
ros::Subscriber和ros::Publisher的“incomplete type”错误,并成功地在你的类中使用这些ROS组件。如果问题仍然存在,可能需要更详细地检查你的代码和编译设置。
以上为生成回答,仅供参考~
-
-
@小伊 在 ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错 中说:
必要的find_package和target_link_libraries指令来链接ROS库
指的是什么,可否给出具体例子
-
在ROS Noetic中使用
boost::shared_ptr<ros::Subscription>时,如果遇到了关于链接ROS库的报错,这通常意味着你的CMakeLists.txt文件可能没有正确配置来找到和链接ROS相关的库。在ROS中,
find_package和target_link_libraries是两个关键的CMake指令,用于指定你的项目依赖哪些ROS包,以及链接到哪些库。下面是一个基本的例子,展示如何在一个ROS节点或库中配置这些指令。1.
find_packagefind_package指令用于告诉CMake你的项目依赖于哪些ROS包。这个指令应该在CMakeLists.txt文件的顶部附近。find_package(CATKIN REQUIRED COMPONENTS roscpp std_msgs )在这个例子中,
roscpp和std_msgs是依赖的包。roscpp是ROS C++客户端库的包,而std_msgs是一个包含标准消息类型的包。你需要根据你项目的具体依赖来修改这个列表。2.
target_link_librariestarget_link_libraries指令用于指定链接到哪些库。在ROS中,通常不需要手动指定链接到ROS的库,因为catkin_make或colcon build会自动处理这些依赖。但是,如果你确实需要手动链接到某些特定的库(虽然这在ROS项目中不常见),你可以这样做:target_link_libraries(your_target_name ${catkin_LIBRARIES})其中
your_target_name是你通过add_executable或add_library创建的目标名称。${catkin_LIBRARIES}是一个变量,它包含了所有通过find_package找到的ROS包所需的库。完整示例
下面是一个完整的
CMakeLists.txt文件示例,用于一个简单的ROS节点,它依赖于roscpp和std_msgs:cmake_minimum_required(VERSION 3.0.2) project(your_project_name) ## Find catkin macros and libraries find_package(CATKIN REQUIRED COMPONENTS roscpp std_msgs ) ## Declare a C++ executable add_executable(your_node_name src/your_node.cpp) ## Specify libraries to link a target against target_link_libraries(your_node_name ${catkin_LIBRARIES}) ## Add cmake target dependencies of the executable/library ## as an example, message headers also have to be generated before nodes add_dependencies(your_node_name ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify include directories include_directories( ${catkin_INCLUDE_DIRS} )在这个例子中,
your_node_name是你的节点的名字,your_node.cpp是节点的源代码文件。your_project_name是你的ROS项目的名字。注意
- 确保你的
CMakeLists.txt文件和源代码文件(如your_node.cpp)位于正确的位置,通常是你的ROS包的src目录下。 - 如果你使用的是
colcon而不是catkin_make来构建你的ROS项目,CMakeLists.txt的配置方式基本相同,但构建过程会有所不同。
通过这些步骤,你应该能够解决关于链接ROS库的报错问题。如果仍然遇到问题,请检查ROS的安装和环境配置是否正确。
以上为生成回答,仅供参考~
- 确保你的
-
我发现了,类型名写错了。。。应该是
ros::Subscriber,不是ros::Subscription。。 -
A admin_ 将这个主题标记为已解决,在