当前位置: 首页 > news >正文

gz中生成模型

生成模型

通过服务调用生成

还记得parameter_bridge 吗?

我们在生成桥接的时候调用了这个cpp文件。

  • 一个 parameter_bridge 实例用于消息传递(传感器数据)。之前的例子

  • 另一个 parameter_bridge 实例用于服务桥接(动态生成模型)。现在的例子


实现多开的方法

1. 启动消息桥接

用第一个 parameter_bridge 实例桥接消息话题,例如传递传感器数据:

ros2 run ros_gz_bridge parameter_bridge /scan@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan
  • 功能:桥接 Gazebo 和 ROS 2 的激光雷达数据。

2. 启动服务桥接

启动第二个 parameter_bridge 实例,用于桥接服务,例如生成模型:

ros2 run ros_gz_bridge parameter_bridge /world/empty/create@ros_gz_interfaces/srv/SpawnEntity
  • 功能:桥接 Gazebo 和 ROS 2 的服务,允许通过 ROS 2 服务生成模型。

3. 发送请求生成模型

在服务桥接启动后,使用以下命令发送生成模型的请求:

ros2 service call /world/empty/create ros_gz_interfaces/srv/SpawnEntity \"{name: 'my_robot', sdf: '<完整的SDF内容>', pose: {position: {x: 0.0, y: 0.0, z: 0.0}, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}"

总结两种调用的区别

功能话题桥接服务桥接
调用命令/scan@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan/world/empty/create@ros_gz_interfaces/srv/SpawnEntity
桥接对象ROS 2 和 Gazebo 的话题ROS 2 和 Gazebo 的服务
桥接方向支持单向或双向(GZ_TO_ROS、ROS_TO_GZ 或 BIDIRECTIONAL)服务请求从 ROS 2 转发到 Gazebo,返回响应
使用场景数据流桥接,如传感器数据动作桥接,如动态生成模型

同时运行的效果

  • 两个 parameter_bridge 实例可以独立运行,并不会互相干扰。
  • 一个处理话题消息,另一个处理服务请求。

parameter_bridge 中服务桥接的实现

在这个调用服务的过程中,我十分好奇,到底是哪一个地方起了作用。

关键实现代码
  1. 解析服务参数

    if (config.ros_type_name.find("/srv/") != std::string::npos) {std::string gz_req_type_name;std::string gz_rep_type_name;if (config.direction == BridgeDirection::ROS_TO_GZ ||config.direction == BridgeDirection::GZ_TO_ROS) {usage();return -1;}if (config.direction == BridgeDirection::BIDIRECTIONAL) {delimPos = arg.find(delim);if (delimPos == std::string::npos || delimPos == 0) {usage();return -1;}gz_req_type_name = arg.substr(0, delimPos);arg.erase(0, delimPos + delim.size());gz_rep_type_name = std::move(arg);}try {bridge_node->add_service_bridge(config.ros_type_name,gz_req_type_name,gz_rep_type_name,config.ros_topic_name);} catch (std::runtime_error & e) {std::cerr << e.what() << std::endl;}continue;
    }
    
    • 解析传入参数,判断是否为服务桥接(ros_type_name 包含 /srv/)。
    • 处理服务的请求类型和响应类型(gz_req_type_namegz_rep_type_name)。
  2. 调用服务桥接方法

    bridge_node->add_service_bridge(config.ros_type_name,gz_req_type_name,gz_rep_type_name,config.ros_topic_name);
    
    • 使用 RosGzBridge::add_service_bridge 方法注册服务桥接。
    • 桥接逻辑会将 ROS 2 的服务请求转发给 Gazebo 服务,并将响应返回给 ROS 2 客户端。
  3. 服务桥接的核心逻辑

    • Gazebo 服务通过内部的 Gazebo Transport 提供功能。
    • ROS 2 服务通过 rclcpp 提供功能。
    • 桥接会订阅 Gazebo 服务,并将其暴露为一个 ROS 2 服务。
    • 响应流向:
      1. ROS 2 客户端 -> ROS 2 服务。
      2. ROS 2 服务 -> Gazebo 服务。
      3. Gazebo 服务 -> ROS 2 服务 -> ROS 2 客户端。

通过自带包生成

ros_gz_sim里面有一个gz_spawn_model的东西,它可以帮助我们在一个已经建成的gz中添加模型。

ros2 launch ros_gz_sim gz_spawn_model.launch.py world:=empty file:=$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf entity_name:=my_vehicle x:=5.0 y:=5.0 z:=0.5

你可以打开这个文件,看看哪个没有默认值,没有默认值的需要你指定参数。一般是 worldfile需要指定参数。

自定义配置

在功能包里面创建xml或者launch.py就行了

例如

<launch><arg name="world" default="" /><arg name="file" default="" /><arg name="model_string" default="" /><arg name="topic" default="" /><arg name="entity_name" default="" /><arg name="allow_renaming" default="False" /><arg name="x" default="" /><arg name="y" default="" /><arg name="z" default="" /><arg name="roll" default="" /><arg name="pitch" default="" /><arg name="yaw" default="" /><gz_spawn_model world="$(var world)"file="$(var file)"model_string="$(var model_string)"topic="$(var topic)"entity_name="$(var entity_name)"allow_renaming="$(var allow_renaming)"x="$(var x)"y="$(var y)"z="$(var z)"roll="$(var roll)"pitch="$(var pitch)"yaw="$(var yaw)"></gz_spawn_model>
</launch>
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Nodedef generate_launch_description():# Declare argumentsreturn LaunchDescription([DeclareLaunchArgument('world', default_value='', description='Name of the Gazebo world'),DeclareLaunchArgument('file', default_value='', description='Path to the model file'),DeclareLaunchArgument('model_string', default_value='', description='Model description as a string'),DeclareLaunchArgument('topic', default_value='', description='Gazebo topic to use'),DeclareLaunchArgument('entity_name', default_value='', description='Name of the entity to spawn'),DeclareLaunchArgument('allow_renaming', default_value='False', description='Allow renaming of the entity'),DeclareLaunchArgument('x', default_value='0.0', description='X position of the model'),DeclareLaunchArgument('y', default_value='0.0', description='Y position of the model'),DeclareLaunchArgument('z', default_value='0.0', description='Z position of the model'),DeclareLaunchArgument('roll', default_value='0.0', description='Roll rotation of the model'),DeclareLaunchArgument('pitch', default_value='0.0', description='Pitch rotation of the model'),DeclareLaunchArgument('yaw', default_value='0.0', description='Yaw rotation of the model'),# Gazebo spawn model nodeNode(package='ros_gz_sim',executable='gz_spawn_model',output='screen',name='spawn_model',parameters=[{'world': LaunchConfiguration('world')},{'file': LaunchConfiguration('file')},{'model_string': LaunchConfiguration('model_string')},{'topic': LaunchConfiguration('topic')},{'entity_name': LaunchConfiguration('entity_name')},{'allow_renaming': LaunchConfiguration('allow_renaming')},{'x': LaunchConfiguration('x')},{'y': LaunchConfiguration('y')},{'z': LaunchConfiguration('z')},{'roll': LaunchConfiguration('roll')},{'pitch': LaunchConfiguration('pitch')},{'yaw': LaunchConfiguration('yaw')}]),])

当然我们也可以简化一些

我们调用了parameter_bridge

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfigurationdef generate_launch_description():# 创建 LaunchDescriptionld = LaunchDescription()# 声明参数ld.add_action(DeclareLaunchArgument('entity_name', default_value='my_robot', description='Name of the entity to spawn'))ld.add_action(DeclareLaunchArgument('file', default_value='/path/to/your/model.sdf', description='Path to the model file'))ld.add_action(DeclareLaunchArgument('x', default_value='0.0', description='X position of the model'))ld.add_action(DeclareLaunchArgument('y', default_value='0.0', description='Y position of the model'))ld.add_action(DeclareLaunchArgument('z', default_value='0.0', description='Z position of the model'))# 配置 parameter_bridge,用于桥接 Gazebo 和 ROS 服务parameter_bridge_cmd = Node(package='ros_gz_bridge',executable='parameter_bridge',arguments=['/world/empty/create@ros_gz_interfaces/srv/SpawnEntity'],output='screen')# 添加到 LaunchDescriptionld.add_action(parameter_bridge_cmd)return ld
XML 元素Python 替代
<arg name="..." />DeclareLaunchArgument
<gz_spawn_model ... />Node,通过 parameters 字段传递参数

同时启动?

在官方教程中,我找到了这一个代码

ros2 launch ros_gz_sim ros_gz_spawn_model.launch.py world:=empty file:=$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf entity_name:=my_vehicle x:=5.0 y:=5.0 z:=0.5 bridge_name:=ros_gz_bridge config_file:=<path_to_your_YAML_file>  

他说,可以同时桥接gz-ros和生成模型


  1. 关键参数的功能
  • world:=empty
    • 指定要加载的 Gazebo 世界为 empty(空白世界)。
    • Gazebo 会在这个世界中加载模型。
  • file:=$(ros2 pkg prefix --share ros_gz_sim_demos)/models/vehicle/model.sdf
    • 指定要加载的模型文件路径。
    • 在这里,加载的是 vehicle 模型的 SDF 文件。
  • entity_name:=my_vehicle
    • 模型的名称,生成后的模型会被命名为 my_vehicle
  • x:=5.0 y:=5.0 z:=0.5
    • 指定模型的初始位置:
      • x:模型在 Gazebo 世界中的 X 坐标。
      • y:模型在 Gazebo 世界中的 Y 坐标。
      • z:模型在 Gazebo 世界中的 Z 坐标。
  • bridge_name:=ros_gz_bridge
    • 定义桥接节点的名称为 ros_gz_bridge
    • 这是 ros_gz_bridge 在 ROS 2 网络中的唯一标识。
  • config_file:=<path_to_your_YAML_file>
    • 指定一个 YAML 配置文件,用于定义要桥接的话题和服务。

通用的桥接 YAML 文件

以下是一个桥接 YAML 配置文件实例。

网络收集,可能会有错误。

bridge_config.yaml

# 桥接 Gazebo 服务到 ROS 2 服务
services:# 模型生成服务- ros_service_name: "/world/empty/create"gz_service_name: "/gazebo/spawn_entity"ros_service_type: "ros_gz_interfaces/srv/SpawnEntity"gz_request_type: "gz.msgs.EntityFactory"gz_response_type: "gz.msgs.Boolean"# 模型删除服务- ros_service_name: "/world/empty/delete"gz_service_name: "/gazebo/delete_entity"ros_service_type: "ros_gz_interfaces/srv/DeleteEntity"gz_request_type: "gz.msgs.Entity"gz_response_type: "gz.msgs.Boolean"# 世界控制服务- ros_service_name: "/world/empty/control"gz_service_name: "/gazebo/control_world"ros_service_type: "ros_gz_interfaces/srv/ControlWorld"gz_request_type: "gz.msgs.WorldControl"gz_response_type: "gz.msgs.Boolean"# 桥接 Gazebo 和 ROS 2 的话题
topics:# 激光雷达数据- ros_topic_name: "/scan"gz_topic_name: "/gazebo/laser_scan"ros_type_name: "sensor_msgs/msg/LaserScan"gz_type_name: "gz.msgs.LaserScan"direction: BIDIRECTIONAL# 摄像头图像数据- ros_topic_name: "/camera/image"gz_topic_name: "/gazebo/camera/image"ros_type_name: "sensor_msgs/msg/Image"gz_type_name: "gz.msgs.Image"direction: GZ_TO_ROS# 深度图像数据- ros_topic_name: "/camera/depth"gz_topic_name: "/gazebo/camera/depth_image"ros_type_name: "sensor_msgs/msg/Image"gz_type_name: "gz.msgs.Image"direction: GZ_TO_ROS# 点云数据- ros_topic_name: "/points"gz_topic_name: "/gazebo/point_cloud"ros_type_name: "sensor_msgs/msg/PointCloud2"gz_type_name: "gz.msgs.PointCloudPacked"direction: GZ_TO_ROS# 机器人位置数据- ros_topic_name: "/robot_pose"gz_topic_name: "/gazebo/pose/info"ros_type_name: "geometry_msgs/msg/Pose"gz_type_name: "gz.msgs.Pose"direction: GZ_TO_ROS# 速度命令- ros_topic_name: "/cmd_vel"gz_topic_name: "/gazebo/cmd_vel"ros_type_name: "geometry_msgs/msg/Twist"gz_type_name: "gz.msgs.Twist"direction: ROS_TO_GZ# 关节状态数据- ros_topic_name: "/joint_states"gz_topic_name: "/gazebo/joint_states"ros_type_name: "sensor_msgs/msg/JointState"gz_type_name: "gz.msgs.Model"direction: GZ_TO_ROS# TF 数据(用于坐标变换)- ros_topic_name: "/tf"gz_topic_name: "/gazebo/tf"ros_type_name: "tf2_msgs/msg/TFMessage"gz_type_name: "gz.msgs.Pose_V"direction: GZ_TO_ROS# 世界状态数据- ros_topic_name: "/world_state"gz_topic_name: "/gazebo/world_state"ros_type_name: "ros_gz_interfaces/msg/WorldState"gz_type_name: "gz.msgs.WorldStatistics"direction: GZ_TO_ROS

相关文章:

gz中生成模型

生成模型 通过服务调用生成 还记得parameter_bridge 吗&#xff1f; 我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递&#xff08;传感器数据&#xff09;。之前的例子 另一个 parameter_bridge 实例用于服务桥接&#xff08;动态生成模型…...

前端(Axios和Promis)

Promise 语法 <script>// 创建promise对象// 此函数需要再传入两个参数,都是函数类型let pnew Promise((resolve,reject)>{if(3>2){resolve({name:"李思蕾",age:23,地址:"河南省"});}else{reject("error");}});console.log(p);p.th…...

AI Agent:重塑业务流程自动化的未来力量(2/30)

《AI Agent&#xff1a;重塑业务流程自动化的未来力量》 摘要&#xff1a;整体思路是先介绍 AI Agent 的基本情况&#xff0c;再深入阐述其实现业务流程自动化的方法和在不同领域的应用&#xff0c;接着分析其价值和面临的挑战&#xff0c;最后得出结论&#xff0c;为读者全面…...

前端页面导出word

html-docx-js bug: vite使用html-docx.js会报错&#xff0c;点击下载上方文件替换即可 正文 npm install html-docx-js -S npm install file-saver -S<template><div id"managerReport">word内容......</div> </template><script>&l…...

【考前预习】1.计算机网络概述

往期推荐 子网掩码、网络地址、广播地址、子网划分及计算-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解&#xff0c;史上最全】-CSDN博客 浅学React和JSX-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生 serverless-CSDN博客 浅谈维度建模、数据分析…...

ubuntu20.04复现 Leg-KILO

这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录&#xff0c;例如 /opt/opencv-3.2&#xff1a;出错&#xff1a; 使用多线程编译错误1&#xff1a; stdlib.h: 没有那个文件或目录错误2&#xff1a;er…...

Ensembl数据库下载参考基因组(常见模式植物)bioinfomatics 工具37

拟南芥参考基因组_拟南芥数据库-CSDN博客 1 Ensembl数据库网址 http://plants.ensembl.org/index.html #官网 如拟南芥等 那么问题来了&#xff0c;基因组fa文件和gff文件在哪里&#xff1f; 2 参考案例 拟南芥基因组fa在这里 注释gff文件在这里...

简单介绍web开发和HTML CSS_web网站开发流程

一、Web 开发&#xff1a;探索互联网世界的基石 1.1 什么是 Web 开发 Web 开发&#xff0c;简单来说&#xff0c;就是构建能够通过浏览器访问的网站的过程。Web 代表着全球广域网&#xff0c;也就是我们熟知的万维网&#xff08;www&#xff09;&#xff0c;它连接着世界各地的…...

Docker 中使用 PHP 通过 Canal 同步 Mysql 数据到 ElasticSearch

一、Mysql 的安装和配置 1.使用 docker 安装 mysql&#xff0c;并且映射端口和 root 账号的密码 # 获取镜像 docker pull mysql:8.0.40-debian# 查看镜像是否下载成功 docker images# 运行msyql镜像 docker run -d -p 3388:3306 --name super-mysql -e MYSQL_ROOT_PASSWORD12…...

数据结构之五:排序

void*类型的实现&#xff1a;排序&#xff08;void*类型&#xff09;-CSDN博客 一、插入排序 1、直接插入排序 思想&#xff1a;把待排序的数据逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 单趟&#x…...

科研绘图系列:R语言绘制热图和散点图以及箱线图(pheatmap, scatterplot boxplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载图1图2图3系统信息参考介绍 R语言绘制热图和散点图以及箱线图(pheatmap, scatterplot & boxplot) 加载R包 library(magrittr) library(dplyr) library(ve…...

基于 webRTC Vue 的局域网 文件传输工具

文件传输工具&#xff0c;匿名加密&#xff0c;只需访问网页&#xff0c;即可连接到其他设备&#xff0c;基于 webRTC 和 Vue.js coturn TURN 服务器 docker pull coturn/coturn docker run -d --networkhost \-v $(pwd)/my.conf:/etc/coturn/turnserver.conf \coturn/coturn…...

LeetCode 718. 最长重复子数组 java题解

https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ 动态规划 class Solution {public int findLength(int[] nums1, int[] nums2) {int len1nums1.length,len2nums2.length;int[][] dpnew int[len11][len21];dp[0][0]0;//没有意义&#xff0c;…...

算法知识-15-深搜

一、概念 深度优先搜索&#xff08;Deep First Search, DFS&#xff09;是一种用于遍历或搜索树或图的算法。这种策略沿着树的深度遍历树的节点&#xff0c;尽可能深地搜索树的分支。 二、关键步骤 选择起点&#xff1a;根据题目要求&#xff0c;选择一个或多个节点作为搜索…...

区块链dapp 开发详解(VUE3.0)

1、安装metamask 插件。 2、使用封装的工具包: wagmi . 3、 wagmi 操作手册地址:connect | Wagmi 4、注意事项&#xff1a; 因为最初是react 版本&#xff0c;所以在VUE版的官方文档有很多地方在 import 用的是 wagmi,需要改为 wagmi/vue 。 连接成功后打印的内容如下&…...

Plugin [id: ‘flutter‘] was not found in any of the following sources解决方法

文章目录 错误描述解决方法修正方案&#xff1a;继续使用 apply from修正后的 build.gradle说明警告的处理进一步验证 错误描述 Plugin [id: ‘flutter’] was not found in any of the following sources: Gradle Core Plugins (not a core plugin, please see https://docs…...

专升本-高数 1

第 0 章&#xff0c;基础知识 一&#xff0c;重要公式 1、完全平方 (ab)a2abb (a-b)a-2abb 2、平方差公式 &#xff08;a-b&#xff09;(ab)a-b 3、立方差公式 a-b(a-b)(aabb) 4、 立方和公式 ab(ab)(a-abb) 二&#xff0c;基本初等函数 1&#xff0c;幂函数 一元二…...

【考前预习】3.计算机网络—数据链路层

往期推荐 【考前预习】2.计算机网络—物理层-CSDN博客 【考前预习】1.计算机网络概述-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生cicd-CSDN博客 子网掩码、网络地址、广播地址、子网划分及计算_子网广播地址-CSDN博客 浅学React和JSX-CSDN博客 目录 1.数…...

DockeUI 弱口令登录漏洞+未授权信息泄露

0x01 产品描述: DockerUI是一款开源的、强大的、轻量级的Docker管理工具。DockerUI覆盖了 docker cli 命令行 95% 以上的命令功能,通过可视化的界面,即使是不熟悉docker命令的用户也可以非常方便的进行Docker和Docker Swarm集群进行管理和维护。0x02 漏洞描述: DockerUI中存…...

【电子元器件】电感基础知识

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时&#xff0c;也能帮助其他需要参考的朋友。如有谬误&#xff0c;欢迎大家进行指正。 一、 电感的基本工作原理 1. 电感的基本工作原理如下&#xff1a; &#xff08;1&#xff09; 当线圈中有电流通过时&#…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...