ros 工作空间下cpp文件调用其他cpp文件的函数或变量

本文详细介绍了在ROS环境中进行节点编程时遇到的问题及解决方法。重点讲解了如何在ROS工作空间中正确使用CMake进行编译,避免出现未定义引用错误。通过修改CMakeLists.txt文件,正确链接源文件,确保ROS节点可以正常编译运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习ros节点编程,在工作空间下添加如下文件:

message.h

#ifndef MESSAGE_H
#define MESSAGE_H
extern int n;
void init_ros();

void publisher();
void sublisher();

#endif

message.cpp

#include "message.h"
#include<stdio.h>
int n=10;
void init_ros()
{
  printf("nihao");
}
void publisher()
{
 printf("nihao");
}

main.cpp

#include "qt_ros_test.h"
#include "message.h"

int main(int argc, char *argv[])
{
    init_ros();
     return 0;
}

如果是普通的c++工程这么调用是没问题的,因为是用g++进行编译的。

但是在ros工作空间这么调用就会出现:undefined reference to `init_ros()'

这是因为ros是用cmake编译的,是要生产cmakelists.txt文件。

所以必须要修改cmakelists.txt文件,在该文件的最后加入:

add_executable(节点名称  src/message.cpp src/message.h )

再进行编译,你会发现通过了。

转载于:https://www.cnblogs.com/fuhang/p/9810388.html

<think>好的,我现在要解决用户的问题:为什么ROS中的回调函数没有被调用,以及如何解决这个问题。用户已经提供了两个引用,可能需要结合这些信息来分析。 首先,我得回忆一下ROS中回调函数的基本工作机制。在ROS中,订阅者(Subscriber)通过回调函数处理接收到的消息。如果回调函数没有被调用,可能有几个常见原因:订阅者未正确初始化、消息类型不匹配、节点未正确运行,者线程阻塞导致回调无法执行。 根据用户提供的引用,引用[1]提到API启动节点的延迟可能很低,但无法获取节点加载的成功失败反馈,也无法卸载节点。这可能意味着节点订阅者的初始化存在问题,但系统没有反馈,导致用户难以察觉。例如,如果节点未能正确加载,订阅者可能没有被创建,从而无法触发回调。 引用[2]提到了ament_export_libraries的调用,这可能与ROS2中的包配置有关。如果库没有正确导出,可能导致节点运行时依赖缺失,进而影响订阅者的创建消息传递。比如,某些依赖库未正确链接,导致订阅者初始化失败,回调函数自然不会被调用。 接下来,我需要将这些可能性结构化,逐步分析可能的原因和解决方法。 可能的原因: 1. **订阅者未正确创建**:检查订阅者的初始化代码是否正确,话题名称是否匹配。 2. **消息类型不匹配**:发布者和订阅者使用的消息类型不一致,导致消息无法反序列化,回调不被触发。 3. **节点未正确运行**:节点可能因为异常退出未启动,导致订阅者不存在。 4. **线程阻塞**:如果回调函数内部有阻塞操作(如长时间循环等待),可能导致整个回调队列停滞。 5. **库依赖问题**:引用[2]中的ament_export_libraries未正确设置,导致必要的库未被加载,影响订阅者的功能。 6. **节点生命周期管理问题**:如引用[1]提到的无法卸载节点,可能存在节点未正确启动提前终止的情况。 解决方法: 1. **检查订阅者初始化代码**:确认话题名称、消息类型和队列大小是否正确。 2. **验证消息类型**:使用`ros2 topic echo``rostopic echo`查看发布的消息类型是否与订阅者一致。 3. **确保节点运行正常**:检查节点是否启动,是否有异常日志输出。 4. **避免阻塞操作**:在回调函数中使用异步处理将耗时操作放到其他线程。 5. **检查包的配置**:确保`ament_export_libraries`正确包含所有依赖库,避免因缺失库导致订阅者失效。 6. **使用调试工具**:如ROS2的`rqt_graph`查看节点和话题的连接情况,确认订阅者是否正确连接。 可能还需要结合用户的具体代码配置进行更详细的分析,比如检查CMakeLists.txt和package.xml是否正确导出依赖库,者查看是否有异常捕获导致错误被忽略。 总结下来,用户需要从订阅者初始化、消息匹配、节点状态、线程管理和依赖配置这几个方面逐一排查。特别是引用中提到的库导出和节点管理问题,可能是容易被忽视的潜在原因。</think>### ROS回调函数未被调用的解决方案 在ROS中回调函数未被调用可能由多种原因导致。以下是逐步排查和解决方法: --- #### 1. **检查订阅者初始化** - **确认话题名称匹配**:发布者和订阅者的话题名称必须完全一致(包括大小写)。 ```cpp // 示例:检查订阅者的话题名称是否正确 ros::Subscriber sub = nh.subscribe("chatter", 10, callback); ``` - **验证消息类型**:发布者与订阅者的消息类型需一致。例如,发布者发送`std_msgs::String`,订阅者也需使用相同类型。 ```bash # 查看话题的消息类型 rostopic info /chatter ``` --- #### 2. **节点运行状态** - **确保节点已启动**:若节点未启动提前终止,订阅者将无法接收消息。检查启动脚本命令行。 - **查看日志输出**:ROS节点崩溃可能导致静默失败。使用`rosrun``roslaunch`时,检查终端输出是否有异常。 --- #### 3. **线程阻塞问题** - **避免在回调中执行耗时操作**:回调函数应快速返回,避免阻塞ROS的线程池。若需处理复杂计算,应将其放入独立线程。 ```python # 示例:在Python中使用线程处理耗时任务 import threading def callback(data): thread = threading.Thread(target=process_data, args=(data,)) thread.start() ``` --- #### 4. **库依赖配置问题(引用[2])** - **检查`ament_export_libraries`**:在ROS2中,若未正确导出依赖库,可能导致节点运行时缺失关键功能。 ```cmake # 在CMakeLists.txt中确保导出库 ament_export_libraries(your_custom_library) ``` - **重新编译和source环境**:修改配置后需重新编译并更新环境变量: ```bash colcon build && source install/setup.bash ``` --- #### 5. **使用调试工具** - **可视化节点连接**:通过`rqt_graph`确认订阅者与发布者是否成功连接。 - **手动发布消息测试**:使用命令行工具发送测试消息,验证回调是否触发: ```bash rostopic pub /chatter std_msgs/String "data: 'test'" ``` --- #### 6. **节点生命周期管理(引用[1])** - **检查节点加载状态**:若使用动态加载节点(如ROS2的`ComposableNode`),需确保节点已正确加载。由于引用[1]指出无法直接获取节点加载反馈,可通过日志外部监控间接验证。 --- ### 相关问题 1. ROS中如何动态加载/卸载节点? 2. `ament_export_libraries`的作用是什么? 3. 如何避免ROS回调函数的线程阻塞? [^1]: 引用[1]提到动态加载节点的反馈缺失问题,需通过其他手段验证节点状态。 [^2]: 引用[2]强调正确导出库依赖以避免运行时错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值