ROS2 C++服务文件编译报错排查:格式化符与链接错误问题
ROS2 C++服务编译错误修复
问题说明
编译ROS2 C++服务节点时,最初怀疑打印int变量的%d格式化符有问题,改成%ld后出现新的链接错误,提示未找到rosidl_typesupport_cpp::get_message_type_support_handle<geometry_msgs::msg::PoseStamped_<std::allocator<void>>>()的定义。
报错日志
> Starting >>> my_cpp_pkg > --- stderr: my_cpp_pkg /usr/bin/ld: CMakeFiles/turtlebot_goal.dir/src/turtlebot_goal.cpp.o: in function > `rclcpp::Publisher<geometry_msgs::msg::PoseStamped_<std::allocator<void> > >, std::allocator<void> >::Publisher(rclcpp::node_interfaces::NodeBaseInterface*, std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> > const&, rclcpp::QoS const&, > rclcpp::PublisherOptionsWithAllocator<std::allocator<void> > const&)': > turtlebot_goal.cpp:(.text._ZN6rclcpp9PublisherIN13geometry_msgs3msg12PoseStamped_ISaIvEEES4_EC2EPNS_15node_interfaces17NodeBaseInterfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3QoSERKNS_29PublisherOptionsWithAllocatorIS4_EE[_ZN6rclcpp9PublisherIN13geometry_msgs3msg12PoseStamped_ISaIvEEES4_EC5EPNS_15node_interfaces17NodeBaseInterfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3QoSERKNS_29PublisherOptionsWithAllocatorIS4_EE]+0x6e): > undefined reference to `rosidl_message_type_support_t const* > rosidl_typesupport_cpp::get_message_type_support_handle<geometry_msgs::msg::PoseStamped_<std::allocator<void> > > >()' collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/turtlebot_goal.dir/build.make:145: turtlebot_goal] Error 1 > make[1]: *** [CMakeFiles/Makefile2:389: > CMakeFiles/turtlebot_goal.dir/all] Error 2 make: *** [Makefile:146: > all] Error 2 > --- Failed <<< my_cpp_pkg [0.26s, exited with code 2]
服务端代码
#include "rclcpp/rclcpp.hpp" #include "example_interfaces/srv/add_two_ints.hpp" using std::placeholders::_1; using std::placeholders::_2; class AddTwoIntsServerNode : public rclcpp::Node { public: AddTwoIntsServerNode() : Node("add_two_ints_server") { server_ = this->create_service<example_interfaces::srv::AddTwoInts>( "add_two_ints", std::bind(&AddTwoIntsServerNode::callbackAddTwoInts, this, _1, _2)); RCLCPP_INFO(this->get_logger(), "Service server has been started."); } private: void callbackAddTwoInts(const example_interfaces::srv::AddTwoInts::Request::SharedPtr request, const example_interfaces::srv::AddTwoInts::Response::SharedPtr response) { response->sum = request->a + request->b; RCLCPP_INFO(this->get_logger(), "%d + %d = %d", request->a, request->b, response->sum); } rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr server_; }; int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = std::make_shared<AddTwoIntsServerNode>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }
错误分析
- 链接错误根源:报错指向
turtlebot_goal.cpp文件,而非当前贴出的服务端代码。该文件中创建了geometry_msgs::msg::PoseStamped类型的Publisher,但编译配置中未正确引入geometry_msgs包的依赖,导致链接时找不到类型支持函数。 - 格式化符问题:
example_interfaces/srv/AddTwoInts中的a、b、sum均为int32_t类型,在多数系统中与int兼容,使用%d完全正确,无需改为%ld,修改后反而可能引发类型不匹配警告。
修复方案
1. 修正CMakeLists.txt依赖
找到包中的CMakeLists.txt,针对turtlebot_goal编译目标添加geometry_msgs依赖:
- 在
find_package段添加:
find_package(geometry_msgs REQUIRED)
- 在
add_executable之后的ament_target_dependencies中加入geometry_msgs:
ament_target_dependencies(turtlebot_goal rclcpp geometry_msgs )
2. 恢复格式化符(若已修改)
将服务端代码中RCLCPP_INFO里的%ld改回%d,匹配int32_t类型的变量。
内容的提问来源于stack exchange,提问作者gurselturkeri
相关产品推荐
相关产品推荐

