XLXdemon 2024-06-17 17:38 采纳率: 0%
浏览 5

ros2通过动态库添加主题

ros2无法通过加动态库的方法对某一个节点实现添加订阅主题吗,我尝试将create_publisher和create_subscriber函数放到动态库中,当只有一个动态库的时候可以正常运行,但是多几个动态库后,程序出现段错误,错误行在create_publisher或create_subscriber函数上

    // 节点构造部分代码
string interface_path = "/opt/user/interface";
for (const auto& iter : boost::filesystem::directory_iterator(interface_path)) {
    if (iter.path().extension() != ".so")
        continue;
    void *handle = dlopen(iter.path().string().c_str(), RTLD_LAZY );
    Add add = NULL;
    add = (Add)dlsym(handle,"add");
    if (add == NULL) {  
        dlclose(handle);
        continue;
    }
    add(shared_from_this(), _mqtt_proc, &_global_db);
    dlclose(handle);
}

// 动态库中部分代码
extern "C" void add(rclcpp::Node::SharedPtr node, MqttProc *mqtt_proc, database_t *global_db)
{
    // ros pub define
    _pub1 = node->create_publisher<std_msgs::msg::String>("/topic1", 1);

    // ros sub
    _sub1 = node->create_subscription<std_msgs::msg::String>("/topic2", 1, callback);

}

gdb堆栈打印如下

img

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-06-17 17:39
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    您好!从您提供的信息来看,您在使用ROS2(Robot Operating System 2)时遇到了动态库加载和节点交互的问题。以下是一些可能的原因和建议的解决步骤:

    原因分析

    1. 动态库依赖冲突:当多个动态库被加载时,如果它们之间存在依赖关系或者使用了不同的ROS2节点实例,可能会导致冲突和段错误。

    2. 内存管理问题dlsymdlclose 在使用时需要小心,如果动态库中的函数依赖于外部的ROS2节点实例,不当的内存管理可能导致段错误。

    3. ROS2节点生命周期管理:在动态库中使用ROS2节点时,需要确保节点的生命周期与动态库的加载和卸载同步,否则可能导致无效的节点引用。

    解决建议

    1. 确保动态库独立性:确保每个动态库都是自包含的,不依赖于其他库中的ROS2节点实例。

    2. 使用ROS2的节点工厂模式:考虑使用ROS2的节点工厂模式来创建节点,而不是在动态库中直接创建。这样可以更好地控制节点的生命周期。

    3. 检查和隔离错误:使用gdb的堆栈跟踪信息来定位具体的错误发生点。根据堆栈跟踪,看起来问题可能出在std::construct_atshared_from_this的使用上。这可能意味着在创建或使用智能指针时出现了问题。

    4. 避免重复加载:确保不要重复加载同一个动态库,这可能会导致未定义行为。

    5. 使用ROS2的日志系统:在动态库中添加日志输出,以帮助诊断问题。

    6. 确保线程安全:如果动态库在多线程环境中使用,确保所有ROS2的操作都是线程安全的。

    代码示例

    这里是一个简化的示例,展示如何在动态库中使用ROS2节点:

    // 动态库中的add函数
    extern "C" void add(rclcpp::Node::SharedPtr node, MqttProc *mqtt_proc, database_t *global_db) {
        // 创建发布者和订阅者
        auto pub = node->create_publisher<std_msgs::msg::String>("/topic1", 1);
        auto sub = node->create_subscription<std_msgs::msg::String>("/topic2", 1, [](const std_msgs::msg::String::SharedPtr msg) {
            // 处理消息
        });
    
        // 确保节点保持活动状态
        rclcpp::spin(node);
    }
    
    // 主程序中的动态库加载
    void load_and_use_plugin(const std::string &path) {
        void *handle = dlopen(path.c_str(), RTLD_LAZY);
        if (!handle) {
            // 处理错误
            return;
        }
    
        using AddFunc = void (*)(rclcpp::Node::SharedPtr, MqttProc*, database_t*);
        AddFunc add = reinterpret_cast<AddFunc>(dlsym(handle, "add"));
        if (add) {
            // 传递ROS2节点和其他参数
            add(node, mqtt_proc, global_db);
        } else {
            // 处理错误
        }
    
        dlclose(handle);
    }
    

    请注意,这只是一个示例,您可能需要根据您的具体情况进行调整。希望这些建议能帮助您解决问题!如果需要进一步的帮助,请随时告诉我。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月17日

悬赏问题

  • ¥15 12864只亮屏 不显示汉字
  • ¥20 三极管1000倍放大电路
  • ¥15 vscode报错如何解决
  • ¥15 前端vue CryptoJS Aes CBC加密后端java解密
  • ¥15 python随机森林对两个excel表格读取,shap报错
  • ¥15 基于STM32心率血氧监测(OLED显示)相关代码运行成功后烧录成功OLED显示屏不显示的原因是什么
  • ¥100 X轴为分离变量(因子变量),如何控制X轴每个分类变量的长度。
  • ¥30 求给定范围的全体素数p的(p-2)/p的连乘积值
  • ¥15 VFP如何使用阿里TTS实现文字转语音?
  • ¥100 需要跳转番茄畅听app的adb命令