自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(122)
  • 收藏
  • 关注

原创 scanf、printf、string函数族

【代码】scanf、printf、string函数族。

2024-05-15 17:02:49 410

原创 非阻塞模式下的读写操作

实现文件IO的非阻塞模式的读写操作。设置为非阻塞模式后,读写不会阻塞,实现标准IO的非阻塞模式的读写操作。

2024-05-15 16:56:56 301

原创 linux串口编程

例如,可以使用OPOST来启用输出处理(执行输出转义字符的功能),使用ONLCR来将输出中的换行符转换为回车换行等。首先,需要打开要使用的串口设备文件,一般在Linux系统中,串口设备文件位于/dev/ttySx或/dev/ttyUSBx,其中x是串口号或USB串口号。可以使用read()函数从串口设备读取数据,使用write()函数将数据写入串口设备。在使用完串口后,需要进行清理和关闭。可以使用tcsetattr()函数将串口参数恢复到默认值,并使用close()函数关闭串口设备文件。

2024-04-29 15:08:46 387

原创 c++-qt项目打包

默认为Debug模式,也是平常开发调试使用的模式,这样的模式生成的可执行文件中包含了程序的各种信息,例如调试信息,未使用的变量等。但是并不是所有的计算机中都安装了Qt的开发环境,在这些计算机中要运行Qt的exe文件,则需要在。Release模式下,生成的可执行文件通常不包含冗余的开发信息,这样的程序虽然不适合开发调试,但是由于体积较小,运行速度快,适合发布给用户使用。Release模式的exe可执行文件在构建目录的release文件夹中,需要注意的是,两种模式的构建目录默认不同。通常称之为动态链接库。

2024-03-03 11:51:05 518 1

原创 c++ Qt 网络连接

表示一个基于TCP的服务器,需要注意的是,此类直接继承了QObject类,不继承QIODevice类,因此不具备任何IO能力。4、众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)UDP(User Datagram Protocol)用户数据报文协议,是不可靠的无连接的协议。4、表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、

2024-02-25 15:27:33 1052 1

原创 c++Qt网络操作

表示一个基于TCP的服务器,需要注意的是,此类直接继承了QObject类,不继承QIODevice类,因此不具备任何IO能力。4、众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)UDP(User Datagram Protocol)用户数据报文协议,是不可靠的无连接的协议。4、表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、

2024-02-14 13:17:59 938

原创 c++ Qt 数据库操作

预处理SQL语句,交给Qt,Qt内部就知道要执行的SQL语句格式,然后在进行参数和占位符的替换,最终执行。Qt本身并没有数据库功能,但是Qt支持调用其他主流的数据库产品,并且这些数据库产品统一了Qt的接口,实际上是一种数据库的中间件。增删改都需要先录入用户输入,然后把用户输入的数据组装成SQL语句,最后执行。数据库相关类无法直接使用,需要在.pro配置文件中添加sql模块。预处理SQL语句,此时SQL语句并没有执行,只是送入到了Qt内部。数据库错误信息类,用户收集数据库底层传递到Qt中的错误信息。

2024-02-14 13:15:51 1463

原创 c++QT文件IO

在实际开发中,两个线程不可能毫无关系的前提下各干各的,最常见的情况是主线程分配一个耗时任务给子线程,子线程需要把耗时任务的执行的执行情况反馈给主线程。子线程往往执行耗时操作,耗时操作又往往伴随着循环,因此并不建议使用粗暴的方式直接停止线程,因为强行停止线程会导致耗时资源无法回收等问题。如果在主线程中实现耗时操作(IO或复杂算法)会导致主线程原本执行的操作被阻塞,甚至无法关闭,形成“假死”的现象。主线程以外的所有线程都是子线程。需要注意的是,QFileDialog只是一个窗口类,本身不具备任何IO的能力。

2024-01-20 09:13:54 1104

原创 qt-c++多窗口编程

实际上parent参数还表示Qt的内存回收机制,如果对象a作为对象b构造函数时的parent参数,表示对象a是对象b的父对象(不是继承关系)。实际上parent参数还表示Qt的内存回收机制,如果对象a作为对象b构造函数时的parent参数,表示对象a是对象b的父对象(不是继承关系)。本次学习主要是在窗口类中实现事件函数,检测到事件的传递,从而利用事件的触发机制,实现一些特定的效果。本次学习主要是在窗口类中实现事件函数,检测到事件的传递,从而利用事件的触发机制,实现一些特定的效果。

2024-01-19 08:43:08 1221

原创 C++常用类

Qt重写了C++的STL中的容器类,相比较于C++STL的容器,Qt的容器类更轻巧,安全和易于使用。Qt中的QString对C++的std::string类进行了重写时,充分考虑到了C++程序员的编程习惯,因此QString几乎支持所有std::string的API。QString使用的。Qt是一个跨平台的开发框架,所以必须要保证各个平台的数据类型长度保持一致,因此Qt为最常见的数据类型提供了新的定义。重新实现了STL中std::map类,QMap也兼容map类的API,也增加了一些新的Qt的API。

2024-01-16 16:27:29 1309

原创 c++qt-基本组件

QLabel用于显式文字或者图片,需要注意的是,QLabel不能与用户交互(不能点击),只能展示使用,因此没有合适的信号函数。把图片导入到项目中,成为项目资源,直接使用Qt的虚拟的资源路径导入图片,可以在任何环境中使用这些资源图片。可以看到在项目中会增加一个界面文件,双击此文件,可以直接使用内置的Designer程序打开并设计。可以把布局看做是一个透明的盒子,内部可以放置子组件,这些内部的子组件会按照布局预设的规则自动排序。布局可以嵌套,对于外层布局而言,内层布局相当于一个外层布局的子组件。

2024-01-11 08:37:23 1246

原创 C++qt-信号-信号槽

函数原型3-信号槽1、概念信号和槽是两种函数,这是Qt在C++基础上新增的特性,类似于其他技术中的回调的概念。信号和槽通过程序员提前设定的“约定”,可以实现对象之间的通信,有两个先决的条件:通信的对象必须都是从QObject类中派生出来的。类中要有Q_OBJECT宏。

2024-01-09 16:28:20 1115

原创 C++-UI入门

按照C++的内存回收机制,子组件应该在父窗口的构造函数中创建,在析构函数中销毁。上面的窗口中什么都没有,实际上可以向窗口中添加若干组件,实现不同的显式和交互效果。样式表,QString为Qt的字符串类型,样式表使用QSS语法(模仿的CSS语法)。横坐标,每个图形的左上角为定位点,横轴的零点在屏幕的最左边,正方向向右。纵坐标,每个图形的左上角为定位点,纵轴的零点在屏幕的最上面,正方向向下。虽然横坐标与纵坐标无法直接修改,但是可以通过下面的函数间接修改。需要注意的是,位置包含边框。1、QWidget类。

2024-01-09 10:48:50 1498

原创 QT入门操作

Qt是一个基于C++的图形用户界面(GUI)开发框架,但是Qt不仅仅能开发界面,还包括很多传统编程中的计数:多线程、数据库、图像处理、网络通信、文件IO。在C语言或者C++中,无论是printf或Cout输出的内容都不分前后台,但是Qt中输出内容是区分前后台的。如果排查了各种问题仍然无法解决,可以尝试取消Shadow build选项,此时项目目录会与工程目录,合二为一,不建议正常使用的用户这样操作。在Qt中一个自定义类的声明都写在.h中,这个类用到的所有其它类的头文件,也在此文件中引入。

2024-01-08 08:28:48 951

原创 C++-nullptr-类型推导

decltype 可以推导表达式的类型,需要注意的是,decltype只会分析表达式的类型,不会具体计算表达式里的值。在C++11 中使用nullptr代替了NULL,作为空指针的表示方式。NULL 在源码当中就是0,因此可能会存在一些二义性的问题。1、nullptr(掌握)(NULL 就是0)使用auto关键字可以推导类型。2、类型推导(auto掌握)

2024-01-08 08:26:02 631

原创 c++-智能指针

每多一个shared_ptr对资源进行管理,引用计数将+1,每个指向该对象的shared_ptr对象销毁时,引用计数-1,最后一个shared_ptr对象销毁时,计数清零,资源对象销毁。作为对auto_ptr的改进,unique_ptr对其他持有的资源对象具有唯一控制权,即不可以通过常规的复制语义转移或拷贝资源对象的控制权。通过weak_ptr的构造函数,参数传入一个持有资源对象的shared_ptr对象或者weak_ptr对象即可创建。lock()函数,通过传入持有资源对象的对象创建新对象。

2024-01-06 10:07:32 412

原创 C++-异常处理

标准异常体系1、概念异常时程序在执行期间产生的问题。C++异常是指在程序运行时发生的特殊情况。比如string::at函数下标越界等。异常提供了一种转移程序控制权的方式。一旦程序出现异常没有经过处理,就会造成程序运行崩溃。处理异常的方式有:抛出异常(throw)和捕获异常(try - catch)2、抛出异常-throw语句可以使用throw语句在代码块中的任何地方抛出异常。throw语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出异常的类型。

2024-01-06 10:04:44 512

原创 C++面向对象核心-权限-多态

(函数隐藏是指在派生类中定义了与基类中同名的函数,从而隐藏了基类中的函数。当通过派生类的对象调用该函数时,实际上调用的是派生类中定义的函数,而不是基类中的函数。中,派生类可以继承基类的成员,不可访问基类的私有成员,基类的公有成员与保护成员在派生类中的权限都是保护权限。虚函数是函数覆盖的前提。中,派生类可以继承基类的成员,但是不可以访问基类的私有成员,基类的公有成员与保护成员在派生类中的权限都是私有权限。当中,派生类可以继承基类的成员,但是不可访问基类的私有成员,基类的公有成员与保护成员在派生类中权限不变。

2024-01-05 09:16:37 1322

原创 C++面向对象核心-继承

以“对象执行中”为轴,上下对称,先创建静态后创建非静态,先创建基类,后创建派生类,先创建成员变量,后创建对象。在派生类的构造函数中,调用基类的构造函数,实际上编译器自动添加派生类的构造函数,调用基类无参构造时,采用的就是这种方式。上面的代码,Son类的功能几乎与Father类重叠,在实际的使用过程中,派生类会做出一些与基类的差异化。基类和派生类是相对的,一个类可能又存在基类,又存在派生的情况,取决于那两个类进行比较。定义学生类,有姓名,学号,性别,年龄等私有成员变量,有构造函数,有打印信息的成员函数。

2024-01-05 09:13:45 1825

原创 C++-模板与容器

几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用的机会。array是C++11新增的容器类型,与传统数组相比更加安全,易于使用。vector向量内部是由数组实现的,比较适合进行随机的存取操作,不擅长插入删除操作。容器是用来存储数据的集合,数据元素可以是任何类型(因为是使用模板实现的)此函数的功能为创建一个长度为len类型是T,默认值为t的数组并输出。迭代器是一个特殊的指针,主要用于容器的元素读写以及遍历。第一个参数为数组默认值,第二个参数为数组的长度。

2024-01-04 09:07:47 1023

原创 c++-运算符重载

成员函数运算符重载相比较于友元函数运算符重载,最大的区别在于,友元函数的第一个传入的参数,在成员函数中用this指针替代。运算符预定义的操作只支持基本数据类型,但是对于自定义类型,也需要类似的运算符操做,此时就可以重新定义这些运算符的功能,使其支持特定类型,完成特定操作。当类中出现指针类型的成员变量时,默认的赋值运算符重载函数类似于默认的浅拷贝构造函数,因此也需要手动编写解决浅拷贝的问题。默认参数使用时需要注意,从被赋予默认参数的参数开始,后面的参数都要赋予默认参数。2 友元函数运算符重载。

2024-01-03 09:21:16 382

原创 Linux系统操作常用指令

(硬链接个数:可以简单的理解为一个文件的文件名个数,比如a文件的文件名有s和j两个,因为s和j指向同一个a,改动s或j都会对a造成改变)绝对路径是一个完整的路径,从/根目录的位置逐层往下找,从根目录开始直到目标文件或目录的路径。例如,假设当前工作目录是 /home/user/,要访问该目录下的一个文件 example.txt,相对路径可以是 ./example.txt 或者 example.txt。那么如果说这个文件特别大,我们一次性的把很大的文件全部读取完成,在把文件里面的信息全部显示在终端上。

2024-01-03 09:17:26 1077

原创 C++-友元-string字符串类

类实现了数据的隐藏和封装,类的数据一般定义为私有成员,仅能通过类的成员函数才能读写。友元关系不具有交换性(比如:类B声明称类Test的友元,类B可以访问类Test中的成员,但是类Test不能访问类B中的私有成员,如果需要访问,需要将类Test声明称类B的友元)当一个类B成为了另一个Test的友元时,类Test的所有成员都可以被类B访问,此时类B就是类Test的友元类。使类B中的成员函数成为类Test的友元成员函数,这样类B的该成员函数就可以访问类Test的所有成员。需要类内声明,类外实现。

2024-01-02 08:56:54 626

原创 面向对象基础-析构函数-this-static-const

实际上this指针指向的就是当前运行的成员函数所绑定的对象。静态成员函数没有this指针,不能在静态成员函数中调用同类中的其他非静态成员函数,但是静态成员函数,可以调用静态成员函数。const修饰的对象被称为常量对象,这种对象的成员变量值无法被修改,也无法调用非const的成员函数。const修饰的成员函数,不能调用非const 修饰的成员函数,只能调用const修饰的成员函数。不能调用非const修饰的成员函数,哪怕这个函数并没有修改成员变量。使用static修饰成员函数,这样的函数就是静态成员函数。

2024-01-02 08:51:01 1208

原创 C++面向对象基础-构造函数

存在,当成员变量出现指针类型时,默认的拷贝构造函数会导致两个对象的成员变量指向同一处,改变一处另一处也会改变不符合面向对象的设计规范,这种现象被称为”浅拷贝“。如果我们有一个默认构造函数,编译器不会创建默认构造函数,会创建拷贝构造函数。如果我们有一个有参构造函数,编译器不会创建默认构造函数,会创建拷贝构造函数。创建有参构造函数,编译器不会创建无参构造函数,会创建拷贝构造函数。创建无参构造函数,编译器不会创建无参构造函数,会创建拷贝构造函数。手动添加构造函数,编译器就不会自动添加构造函数。

2023-12-31 14:30:03 508

原创 面向对象基础-类与对象-封装

比如说:睡觉、吃饭、打呼噜、打架、唱、跳、rap、打篮球。封装指的是,将类的一些属性和细节隐藏。属性:表示一些特征项的数值,比如说:身高、体重、年龄、性别。必须使用new关键字创建,使用指针保存(当前对象的首地址,调用构造函数)。堆内存对象调用成员时,使用->而不是"."(英文“.”自动生成“->”)类中最基础的内容包括两部分,一个是属性、一个是行为。规定手机的行为:打游戏、爆炸、飞、打电话、播放音乐。类:类是一个抽象的概念,用于描述一类对象的特点。规定手机的属性:品牌、型号、重量、尺寸。

2023-12-31 14:22:26 693

原创 C++-赋值-string字符串类-函数

我们添加的inline关键字,将函数声明为内联函数。内联函数用于取代C语言中宏定义的函数,内联函数的正确使用可以提升程序的执行效率。内联函数在编译的时候,直接把函数体展开到主函数中遍历,在运行期间可以减少调用的开销。string在绝大多数情况下可以替代C语言中的字符串,不用担心内存是否足够和字符串等等。C++中允许多个函数使用同一个名称,这种用法就是函数重载。函数重载要求函数名称相同,但是参数不同(类型或者数量)或者前后顺序不同。string不是C++的基本数据类型,他是一个C++标准库中的字符串类。

2023-12-29 08:57:29 1307

原创 二-从C到C++

4)声明引用的时候,初始化的值可以是纯数值,但是此时需要使用const关键字修饰引用,表示该引用为常量引用,这样的引用的值不能改变。引用作为参数进行定义的时候,在参数传递时,是不会产生副本的,这样会提高运行效率,我们在正常编程当中,建议使用引用进行传递参数。以达到引用的安全性。写一个函数,函数有两个参数a和b,函数的功能是交换两个传入的参数【原来变量】的值。5)可以将变量引用的地址赋值给一个指针,此时指针指向的还是原来的变量。6)可以使用const修饰引用,此时如果原变量的值改变,引用的值也改变。

2023-12-29 08:55:17 1082

原创 一、C++简介

上面这种思想就是典型的面向过程的思想,这种思想关注的重点是“过程”,“过程”指的是一系列有序的步骤,只要按照这个步骤来做,就可以得到想要的结果。这种思维方式偏向于计算机执行命令的本质,通常程序位一些有序的命令,这样的程序特点是执行效率高(因为都是亲历亲为)。面向对象的语言,关注的重点是“对象”。在计算机当中,“对象”可以理解为一系列由于某种联系而聚焦在一起的数据,在编程的过程当中,处理对象之间的关系,这种思考方式更近于人类的思考方式。3、在弹出的窗口中,先输入项目名称,在设定项目路径,最后点击“下一步”。

2023-12-28 18:35:42 664

原创 Linux内核定时器-模块导出符号表

应用层两个app程序,app1中拥有一个add函数,app1运行时app2是否可以调用app1中的add函数?在驱动的一个模块中,想使用另外一个模块中的函数/变量,只需要使用EXPORT_SYMBOL_GPL将变量或者函数的地址给导出。如果调用者和提供者时两个独立(xx.ko)驱动模块,他们间传递地址的时候,是通过Module.symvers传递的。代码更精简,一些代码可以不用写,直接调用别人写好的函数就可以。编写驱动代码找到其他驱动中的函数,需要用模块导出符号表将函数导出,被人才可以使用这个函数。

2023-12-28 08:58:30 349

原创 Linux内核中断

Linux内核中断ARM里当按下按键的时候,他首先会执行汇编文件start.s里面的异常向量表里面的irq在irq里面进行一些操作。再跳转到C的do_irq();进行操作:1)判断中断的序号;2)处理中断;3)清除中断;Linux内核实现和ARM裸机实现中断的原理是一样的。

2023-12-27 20:11:35 1356

原创 ioctl函数-控制设备的I/O通道

在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对应一个命令码,做出一些相应的操作。= 4G的数字,所以可以使用,内核的想法是:每一个数字代表一个,功能和数字一一对应,但是不一样的驱动使用的时候相同也是可以的)对于使用ioctl函数时,主要的就是请求码的设计,请求码主要在sys/ioctl.h文件里面进行了设计。(序号:表示同类型中的第几个,当开灯的时候写0,那关的时候就不写0)。(类型:组合成一个唯一的不重合的整数,一般传一个字符)一个一个看,鼠标放在。

2023-12-27 08:53:56 914

原创 根文件系统制作-移植

根文件系统镜像:将根文件系统按照某种格式进行打包压缩后生成的单个文件 rootfs-----> ramdisk.img。向文件/proc/sys/kernel/hotplug写入字符串"/sbin/mdev" 其实就是告诉内核驱动将来创建设备文件的程序是/sbin/mdev。dev: 设备文件(被操作系统识别的设备才有对应的文件,即设备运行时)lib: 库文件、比如C的标准库(从交叉编译工具链中复制的)解决办法:将交叉编译工具链中的库,拷贝到根文件系统的lib目录。

2023-12-26 08:52:33 874

原创 通过字符设备驱动点亮板子上的led灯

IS_ERR(): 返回值为0,不在错误码地址范围,非0,在错误码地址范围,内核从0xffffffff 地址开始往地址减少的方向,预留了4K空间用来作为错误码的地址。copy_from_user(内核空间首地址,用户空间地址,拷贝字节数);copy_to_user(用户空间地址,内核空间首地址,拷贝字节数);MKDEV(主设备号,次设备号),NULL,设备节点的名字);1、//通过虚拟地址对寄存器更改设置值,实行对硬件的初始化。,在linux内核启动之后,在使用地址的时候,操作的全是。

2023-12-25 09:19:31 843

原创 字符设备驱动开发-注册-设备文件创建

一、字符设备驱动linux系统中一切皆文件1、应用层: APP1 APP2 ...fd = open("led驱动的文件",O_RDWR);read(fd);write();close();2、内核层:对灯写一个驱动//(close)cdev:设备号1 设备号2 设备号n设备驱动1 设备驱动2 ....设备驱动n设备号:32位,无符号数字高12位 :主设备号 :区分哪一类设备。

2023-12-22 09:12:53 1611

原创 驱动开发-1

注:可中断,不可中断,就是是否被信号打断。:通过网络协议栈(OSI,TCP)对数据进程封装和拆解过程(数据发送和接收是通过网卡驱动完成的,网卡驱动不会产生文件(在Linux系统dev下面没有相应的文件),所以不能用open等函数,而是使用的socket)。注:1G的物理内存映射成0~4G的虚拟内存,每个进程都可以访问内核,0~3G是每个进程单独拥有的,3G~4G是所有的共有的。* byte, short, ushort, int, uint, long, ulong (没有找到char!

2023-12-21 08:33:52 1274

原创 u_boot 分析

根据bootm 命令执行do_bootm_states函数,658行非常重要,通过bootm_os_get_boot_func查找系统启动函数,参数images->os.os为系统类型,函数返回值是查找到的系统启动函数do_bootm_linux。find_cmd(argv[0])函数在common\command.c中346行,首先看360行__u_boot_cmd_start和__u_boot_cmd_end,这两个东西搜遍代码是搜不到的,它在链接脚本里,C语言中,链接脚本也可以传入值。

2023-12-20 10:25:15 925

原创 网络环境搭建及uboot配置

这一章节主要分为两大块:一个为产品阶段即:Linux内核、根文件系统、uboot全部存储到硬盘内,另一个为研发阶段,研发阶段因为需要反复调试,所以需要我们把跟文件系统放到NFS内使用共享的方式,Linux内核放到tftp下进行传输,uboot最好使用SD卡的方式。三星公司没有对S5P6818的源码,开源到Linux内核中,所以不能从官网下载linux内核源码,使用samsung提供的内核源码。内核是一个操作系统的核心,提供了操作系统最基本的功能,是操作系统工作的基础,决定着整个系统的性能和稳定性。

2023-12-19 08:58:51 1125

原创 系统移植导学

通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。(ping 其它机器过程:本机网卡驱动,到内核,内核处理这个驱动,发送ping的包到另一个系统的网卡,处理这个包,把包的内容放到协议站(在内核里面),识别到ping的包,然后通过网卡驱动,到网卡,返回一个包(都会到真正物理硬件)),是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,其主要作用为:引导系统的启动!内核就像一个库,提供了一组面向系统的命令。

2023-12-18 09:31:42 48

原创 CPU控制硬件原理

1.GPIOxALTFN0和GPIOxALTFN1两个寄存器:控制一个GPIO引脚功能,A类GPIO有32个引脚,即需要八个字节管理A类GPIO引脚。查看对应GPIO硬件映射的地址(寄存器:这将能控制硬件的空间叫寄存器,在cpu外,有地址)--》找到寄存器描述(Register Description)告诉你地址空间是如何映射的,便于我们找到对应的硬件地址。CPU不能直接控制硬件,硬件是由其对应的外部寄存器(存储器)来控制的。引脚是硬件,硬件控制都会隐射到内存的一个地址。引脚是芯片里外交流的载体。

2023-12-15 11:54:56 196

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除