NDIS驱动开发-NET_BUFFER体系

网络数据由通过网络发送或接收的数据包组成。 NDIS 提供数据结构来描述和组织此类数据。 NDIS 6.0 及更高版本的主要网络数据结构包括:

  • NET_BUFFER
  • NET_BUFFER LIST
  • NET_BUFFER_LIST_CONTEXT

它们之间的关系如下:

在 NDIS 6.0 及更高版本中, NET_BUFFER 是打包网络数据的基本构建基块。 每个NET_BUFFER结构都有一个 MDL 链。 MDL 将数据缓冲区的地址映射到NET_BUFFER结构指定的数据空间。 此数据映射与 NDIS 5.x 的 MDL 链相同, 更早版本的驱动程序在 NDIS_PACKET 结构中使用 。 NDIS 也提供用于操作 MDL 链的函数。

可以将多个NET_BUFFER结构附加到NET_BUFFER_LIST结构。 NET_BUFFER结构组织为以 NULL 结尾的单独链接列表。 只有源自 NET_BUFFER_LIST 结构的驱动程序(即 NDIS)应直接修改链接列表以插入和删除NET_BUFFER结构。

NET_BUFFER LIST 结构包含描述附加到列表的所有 NET_BUFFER 结构的信息。 如果驱动程序需要额外的空间来存储上下文信息,驱动程序可以将此类信息存储在NET_BUFFER_LIST_CONTEXT结构中。 NDIS 提供用于分配、释放和访问NET_BUFFER_LIST_CONTEXT结构中的数据的函数。

可以附加多个NET_BUFFER_LIST结构以形成NET_BUFFER_LIST结构的列表。 NET_BUFFER_LIST结构组织为以 NULL 结尾的单独链接列表。 驱动程序可以直接修改链接列表以插入和删除NET_BUFFER_LIST结构。

NET_BUFFER 结构

NDIS 6.0 及更高版本的 NET_BUFFER 结构类似于 NDIS 5 使用的 NDIS_PACKET 结构。x 和更早版本的驱动程序。 每个NET_BUFFER结构打包一个网络数据包。

下图显示了NET_BUFFER结构中的字段:

NET_BUFFER结构包括 NetBufferHeader 成员中的NET_BUFFER_HEADER结构。 NET_BUFFER_HEADER 结构包括 NetBufferData 成员中的NET_BUFFER_DATA结构, 应使用 NDIS 宏访问NET_BUFFER结构成员。 

某些 NET_BUFFER 结构成员仅由 NDIS 使用。 驱动程序通常使用的成员包括:

  • ProtocolReserved:保留供协议驱动程序使用;
  • MiniportReserved:保留供微型端口驱动程序使用;
  • NdisPoolHandle:指定池句柄,该句柄标识从中分配NET_BUFFER结构的NET_BUFFER池;
  • NEXT:指定指向NET_BUFFER结构链接列表中的下一个NET_BUFFER结构的指针。 如果这是列表中的最后一个NET_BUFFER结构,则此成员为 NULL;
  • DataLength:指定 MDL 链中网络数据的长度(以字节为单位);
  • DataOffset:指定从 MDL 链中内存开始到 MDL 链中网络数据开始的偏移量(以字节为单位);
  • CurrentMdl:指定指向当前驱动程序正在使用的第一个 MDL 的指针。 此指针提供一种优化,通过跳过当前驱动程序未使用的任何 MDL 来提高性能;
  • CurrentMdlOffset:指定 MDL 中已用数据空间开头的偏移量(以字节为单位),该偏移量由 NET_BUFFER 结构的 CurrentMdl 成员指定;

下图显示了 CurrentMdl、 CurrentMdlOffset、 DataOffset 和 DataLength 成员与数据空间之间的关系:

 

NDIS 提供用于管理 MDL 链中的数据空间的函数。 驱动程序如何使用数据空间与当前驱动程序一起动态更改。 有时,当前驱动程序当前未使用的数据空间。 尽管未使用的数据空间当前未使用,但它可以包含有效数据。 例如,在接收路径上, 未使用的数据空间可以包含较低级别驱动程序使用的信息。

以下术语和定义描述了 NET_BUFFER 数据空间的元素:

  • 已用数据空间:已用数据空间 包含当前驱动程序当前使用的数据。 驱动程序通过撤退操作增加 已用数据空间 ,并通过高级操作减少 已用数据空间;
  • 未使用的数据空间:当前驱动程序当前未使用此数据空间;
  • 数据总大小:总数据大小是 已用数据空间 与 未使用数据空间大小之和。 若要计算总大小,请将 DataOffset 添加到 DataLength ;
  • 撤退:撤退操作会增加 已用数据空间的大小;
  • 前进:前进操作会减小 已用数据空间的大小;
 NET_BUFFER_LIST结构

NET_BUFFER_LIST结构包含NET_BUFFER结构的链接列表。下图显示了NET_BUFFER_LIST结构中的字段:

NET_BUFFER_LIST结构包括 NetBufferListHeader 成员中的NET_BUFFER_LIST_HEADER结构。 NET_BUFFER_LIST_HEADER结构包括 NetBufferListData 成员中的NET_BUFFER_LIST_DATA结构。 应使用 NDIS 宏访问NET_BUFFER_LIST结构成员。 

某些成员仅由 NDIS 使用。 驱动程序最有可能使用的成员在以下列表中定义:

  • ParentNetBufferList:如果 NET_BUFFER_LIST 结构是从克隆、分段或重新组合的父类派生的子级, 则 ParentNetBufferList 指定指向父NET_BUFFER_LIST结构的指针。 否则,此参数为 NULL;
  • NdisPoolHandle:指定池句柄,该句柄标识从中分配NET_BUFFER_LIST结构的NET_BUFFER_LIST池;
  • ProtocolReserved:保留供协议驱动程序使用;
  • MiniportReserved:保留供微型端口驱动程序使用;
  • SourceHandle:NDIS 使用以下驱动程序提供的例程之一在绑定或附加操作中提供给驱动程序的句柄:微型端口驱动程序:MiniportInitializeEx、协议驱动程序:ProtocolBindAdapterEx、Filter驱动程序:FilterAttach。NDIS 使用 SourceHandle 将NET_BUFFER_LIST结构返回到发送NET_BUFFER_LIST结构的驱动程序。 NDIS 驱动程序不应读取此句柄;
  • ChildRefCount:如果 NET_BUFFER_LIST 结构是父类(具有由克隆、片段或重新组合操作) 派生的子级, 则 ChildRefCount 指定现有子级的数目。 否则此参数为零;
  • Flags:保留用于NET_BUFFER_LIST结构的属性的未来规范。 目前没有可用于驱动程序的标志;
  • Status:指定此NET_BUFFER_LIST结构的网络数据操作的最终完成状态。 微型端口驱动程序在完成发送操作之前写入此值;
  • NetBufferListInfo:指定 列表中 所有NET_BUFFER结构通用 NET_BUFFER_LIST 结构信息。 此信息通常称为“带外 (OOB) 数据”;
  • Next: 指定指向NET_BUFFER_LIST结构链接列表中的下一个NET_BUFFER_LIST结构的指针。 如果NET_BUFFER_LIST结构是列表中的最后一个结构,则此成员为 NULL;
  • FirstNetBuffer:指定指向与此NET_BUFFER_LIST结构关联的NET_BUFFER结构链接列表中的第一个NET_BUFFER结构的指针;

注意Context 是指向 NET_BUFFER_LIST_CONTEXT 结构的指针。 NDIS 提供宏和函数来操作上下文中的数据。

NET_BUFFER_LIST_CONTEXT结构

NDIS 驱动程序使用 NET_BUFFER_LIST_CONTEXT 结构来存储与 NET_BUFFER_LIST 结构关联的其他数据。 NET_BUFFER_LIST 结构的 Context 成员是指向NET_BUFFER_LIST_CONTEXT结构的指针。 存储在NET_BUFFER_LIST_CONTEXT结构中的信息对堆栈中的 NDIS 和其他驱动程序是不透明的。

下图显示了NET_BUFFER_LIST_CONTEXT结构中的字段:

NET_BUFFER_LIST_CONTEXT结构包括包含上下文数据的 ContextData 成员。 此数据可以是驱动程序 NET_BUFFER_LIST结构所需的 任何上下文信息。

驱动程序应使用以下 NDIS 宏和函数来访问和操作NET_BUFFER_LIST_CONTEXT结构中的成员:

NdisAllocateNetBufferListContext

NdisFreeNetBufferListContext

NET_BUFFER_LIST_CONTEXT_DATA_START

NET_BUFFER_LIST_CONTEXT_DATA_SIZE

发送网络数据

下图演示了一个基本的发送操作,该操作涉及协议驱动程序、NDIS 和微型端口驱动程序:

协议驱动程序调用 NdisSendNetBufferLists 函数以发送绑定上的 NET_BUFFER_LIST 结构。 NDIS 调用微型端口驱动程序的 MiniportSendNetBufferLists 函数,将NET_BUFFER_LIST结构转发到基础微型端口驱动程序。

所有基于NET_BUFFER的发送操作都是异步的。 完成时,微型端口驱动程序使用适当的状态代码调用 NdisMSendNetBufferListsComplete 函数。 每个NET_BUFFER_LIST结构的发送可以单独完成。 每次微型端口驱动程序调用 NdisMSendNetBufferListsComplete 时,NDIS 都会调用协议驱动程序的 ProtocolSendNetBufferListsComplete 函数。

一旦 NDIS 调用协议驱动程序的 ProtocolSendNetBufferListsComplete 函数,协议驱动程序就可以回收NET_BUFFER_LIST结构以及所有相关结构和数据的所有权。

微型端口驱动程序或 NDIS 可以按任意顺序返回 NET_BUFFER_LIST 结构。 协议驱动程序保证未修改附加到每个 NET_BUFFER_LIST 结构的NET_BUFFER结构列表。

任何 NDIS 驱动程序都可以在NET_BUFFER_LIST结构中分离NET_BUFFER结构。 任何 NDIS 驱动程序还可以在NET_BUFFER结构中分离 MDL。 但是,驱动程序必须始终返回具有原始形式的NET_BUFFER结构和 MDL 的NET_BUFFER_LIST结构。 例如,中间驱动程序可以将NET_BUFFER_LIST分成两个新的NET_BUFFER_LIST结构,并将部分原始数据传递给下一个驱动程序。 但是,当中间驱动程序完成原始NET_BUFFER_LIST它必须返回包含原始NET_BUFFER结构和 MDL 的完整NET_BUFFER_LIST。

协议驱动程序将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在调用 NdisOpenAdapterEx 函数时提供的 NdisBindingHandle。 NDIS 使用 SourceHandle 成员将NET_BUFFER_LIST结构返回到发送NET_BUFFER_LIST结构的协议驱动程序。

中间驱动程序还会将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在调用 NdisOpenAdapterEx 时提供的 NdisBindingHandle 值。 如果中间驱动程序转发发送请求,则驱动程序必须在写入 SourceHandle 成员之前保存过度驱动程序提供的 SourceHandle 值。 当 NDIS 将转发NET_BUFFER_LIST结构返回到中间驱动程序时,中间驱动程序必须还原它保存的 SourceHandle 。

接收网络数据

下图演示了一个基本的接收操作,该操作涉及微型端口驱动程序、NDIS 和协议驱动程序。

微型端口驱动程序调用 NdisMIndicateReceiveNetBufferLists 函数,以指示更高级别驱动程序 NET_BUFFER 结构。 每个NET_BUFFER结构通常应附加到单独的 NET_BUFFER_LIST 结构。 这样,协议驱动程序就可以创建NET_BUFFER_LIST结构的原始列表的子集,并将其转发到不同的客户端。 某些驱动程序(例如本机 IEEE 802.11 微型端口驱动程序)可能会将多个NET_BUFFER结构附加到NET_BUFFER_LIST结构。

链接所有NET_BUFFER_LIST结构后,微型端口驱动程序会将指向列表中第一个NET_BUFFER_LIST结构的指针传递给 NdisMIndicateReceiveNetBufferLists 函数。 NDIS 检查NET_BUFFER_LIST结构,并调用与NET_BUFFER_LIST结构关联的每个协议驱动程序的 ProtocolReceiveNetBufferLists 函数。 NDIS 传递列表的子集,该子集仅包含与每个协议驱动程序的正确绑定关联的NET_BUFFER_LIST结构。 NDIS 将 NET_BUFFER_LIST 结构中指定的 NetBufferListFrameType 值与每个协议驱动程序注册的帧类型匹配。

如果设置了传递给协议驱动程序的 ProtocolReceiveNetBufferLists 函数的 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,则 NDIS 会在 ProtocolReceiveNetBufferLists 调用返回后立即重新获得NET_BUFFER_LIST结构的所有权。

注意 如果设置了NDIS_RECEIVE_FLAGS_RESOURCES标志,则协议驱动程序必须在链接列表中保留原始NET_BUFFER_LIST结构集。 例如,设置此标志时,驱动程序可能会处理这些结构,并指示它们一次上堆栈一个,但在函数返回之前,它必须还原原始链接列表。

如果未设置传递给协议驱动程序 ProtocolReceiveNetBufferLists 函数的 ReceiveFlags 参数中的NDIS_RECEIVE_FLAGS_RESOURCES标志,则协议驱动程序可以保留NET_BUFFER_LIST结构的所有权。 在这种情况下,协议驱动程序必须通过调用 NdisReturnNetBufferLists 函数返回NET_BUFFER_LIST结构。

如果微型端口驱动程序在接收资源上运行不足,则可以在调用 NdisMIndicateReceiveNetBufferLists 时在 ReceiveFlags 参数中设置NDIS_RECEIVE_FLAGS_RESOURCES标志。 在这种情况下,驱动程序可以在 NdisMIndicateReceiveNetBufferLists 返回后立即回收所有指示NET_BUFFER_LIST结构和嵌入NET_BUFFER结构的所有权。 指示设置了NDIS_RECEIVE_FLAGS_RESOURCES标志的NET_BUFFER结构会强制协议驱动程序复制数据,因此应避免这样做。 微型端口驱动程序应检测即将耗尽接收资源的时间,并采取任何必要的步骤来避免这种情况。

NDIS 在协议驱动程序调用 NdisReturnNetBufferLists 后,调用微型端口驱动程序的 MiniportReturnNetBufferLists 函数。

注意 如果微型端口驱动程序指示NET_BUFFER_LIST结构并设置了NDIS_RECEIVE_FLAGS_RESOURCES标志,这并不意味着 NDIS 会向具有相同状态的协议驱动程序指示NET_BUFFER_LIST结构。 例如,NDIS 可以复制设置了 NDIS_RECEIVE_FLAGS_RESOURCES 标志的NET_BUFFER_LIST结构,并在清除标志的情况下指示复制到协议驱动程序。

NDIS 可以任意顺序 和 任意组合将NET_BUFFER_LIST结构返回到微型端口驱动程序。 也就是说,通过调用 MiniportReturnNetBufferLists 函数返回给微型端口驱动程序的NET_BUFFER_LIST结构的链接列表可以具有以前对 NdisMIndicateReceiveNetBufferLists 的不同调用NET_BUFFER_LIST结构。

微型端口驱动程序应将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 NDIS 在 MiniportInitializeEx 函数中提供给微型端口驱动程序的 MiniportAdapterHandle。 筛选器驱动程序必须将筛选器驱动程序源自的每个NET_BUFFER_LIST结构的 SourceHandle 成员设置为筛选器的 NdisFilterHandle ,NDIS 在 FilterAttach 函数中提供给筛选器驱动程序。 筛选器驱动程序不得修改任何非筛选器驱动程序产生的NET_BUFFER_LIST结构中的 SourceHandle 成员。

中间驱动程序还将 NET_BUFFER_LIST 结构中的 SourceHandle 成员设置为 MiniportAdapterHandle 值,NDIS 在 MiniportInitializeEx 函数中提供给中间驱动程序。 如果中间驱动程序转发接收指示,则驱动程序必须在写入 SourceHandle 成员之前保存基础驱动程序提供的 SourceHandle 值。 当 NDIS 将转发NET_BUFFER_LIST结构返回到中间驱动程序时,中间驱动程序必须还原它保存的 SourceHandle 。

收发网络数据包的代码

下面是实际使用的一个发送数据包的例子:

PNET_BUFFER_LIST CreateBroadCast(
IN NDIS_HANDLE FilterHandle, 
IN UCHAR Buffer[MAX_BOASTCAST]
)
{PUCHAR               pData          = NULL;PUCHAR               pMdlData       = NULL;PMDL                 pMdl           = NULL;PNET_BUFFER_LIST     pNetBufferList = NULL;// 分配一个内存pData = (PUCHAR)NdisAllocateMemoryWithTagPriority(FilterHandle, MAX_BOASTCAST, ALLOC_TAG, LowPoolPriority);// 分配MDLpMdl = NdisAllocateMdl(FilterHandle, pData, FILTER_ALLOC_TAG);// 获取MDL的地址pMdlData = (PUCHAR)MmGetSystemAddressForMdlSafe(pMdl, LowPoolPriority);// 将数据复制到MDLNdisMoveMemory(pMdlData, &Buffer[0], MAX_BOASTCAST);// 创建一个NetBufferListpNetBufferList = NdisAllocateNetBufferAndNetBufferList(pFilter->SendNetBufferListPool,0,0,           // back fill sizepMdl,0,          // Data offsetMAX_BOASTCAST);pNetBufferList->SourceHandle = pFilter->FilterHandle;return pNetBufferList;
}

以及接收数据包的例子:

ULONG AnalysisNetBuffer(
IN NDIS_HANDLE pFilter, 
IN PNET_BUFFER_LIST NetBufferLists
)
{PUCHAR				pData      = NULL;PNET_BUFFER_LIST	pCurrNbl   = NetBufferLists;PNET_BUFFER			pCurrBuff  = NULL;PNET_BUFFER         pNextBuff  = NULL;   PMDL				pMdl       = NULL;ULONG				ulOffset   = 0;int					nDataLen   = 0;ULONG               ulError    = FC_GIGE_SUCCESS;while (pCurrNbl){pCurrBuff = NET_BUFFER_LIST_FIRST_NB(pCurrNbl);while(pCurrBuff){ulOffset  = NET_BUFFER_DATA_OFFSET(pCurrBuff);pMdl      = NET_BUFFER_FIRST_MDL(pCurrBuff);nDataLen  = NET_BUFFER_DATA_LENGTH(pCurrBuff);if(pMdl == NULL || nDataLen == 0) continue;pData     = (UCHAR*)MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);pNextBuff = NET_BUFFER_NEXT_NB(pCurrBuff);if(NULL == pNextBuff){// 获取真正的数据地址,此处的pData指向的就是数据地址pData    = pData + ulOffset;nDataLen = nDataLen - ulOffset;}else{;}pCurrBuff = pNextBuff;}pCurrNbl = NET_BUFFER_LIST_NEXT_NBL(pCurrNbl);}return ulError;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

串口调试助手中文乱码 解决方案

输出乱码 一般,当串口调试助手输出乱码时,可能有以下几个原因: 波特率设置错误:串口通信需要保证发送和接收的设备使用相同的波特率。请检查串口调试助手和目标设备的波特率设置是否一致。 数据位、停止位或校验位设置错误&…

【目标解算】相机内外参数详细解读+坐标系转换

一、相机参数介绍 1.1 相机内参矩阵 概念:内参矩阵用于描述相机的内部参数,它包含了相机的焦距、主点坐标和图像的畸变等信息。内参矩阵的形式通常为一个3x3的矩阵,常用表示为K。内参矩阵可以将相机坐标系中的三维点映射到图像平面上的二维…

linux安装mysql后,配置mysql,并连接navicat软件

Xshell连接登陆服务器 输入全局命令 mysql -u root -p 回车后,输入密码,不显示输入的密码 注意mysql服务状态,是否运行等 修改配置文件my.cnf,这里没找到就找my.ini,指定有一个是对的 find / -name my.cnf 接下…

GPT-4你了解多少呢

一、引言 在人工智能(AI)领域,自然语言处理(NLP)技术一直备受关注。近年来,随着深度学习技术的飞速发展,NLP领域也取得了显著进步。GPT-4,作为OpenAI公司最新发布的自然语言处理模型…

京东二面:为什么Netty要造FastThreadLocal?

FastThreadLocal 从字面意义上来看,它是“Fast”“ThreadLocal”的结合体,寓意为快速的 ThreadLocal。那么,问题来了,Netty 为什么要再造一个 FastThreadLocal?FastThreadLocal 运行快的原因是啥?除了快之外…

linnux上安装php zip(ZipArchive)、libzip扩展

安装顺序: 安装zip(ZipArchive),需要先安装libzip扩展 安装libzip,需要先安装cmake 按照cmake、libzip、zip的先后顺序安装 下面的命令都是Linux命令 1、安装cmake 确认是否已安装 cmake --version cmake官网 未安装…

【Paddle】稀疏计算的使用指南 稀疏ResNet的学习心得 (2) + Paddle3D应用实例稀疏 ResNet代码解读 (1.6w字超详细)

【Paddle】稀疏计算的使用指南 & 稀疏ResNet的学习心得 Paddle3D应用实例稀疏 ResNet代码解读 写在最前面一、稀疏格式简介1. COO(Coordinate Format)2. CSR(Compressed Sparse Row Format) 二、Paddle稀疏张量支持1. 创建 C…

SQL刷题笔记day6——转战LeetCode

1 第二高的薪水 ​ 我的代码: SELECT Salary SecondHighestSalary FROM Employee ORDER BY Salary DESC LIMIT 1, 1 我的代码不满足示例2的情况:如果没有第 2 高的薪资,即表里可能只有一条记录,这个解答会被评测为 Wrong Answ…

整理了六个正规靠谱的兼职赚钱软件,适合普通人做的兼职副业~

​随着互联网时代的到来,越来越多的人选择通过互联网赚钱。在这篇文章中,我们将探讨一些可以在网上长期赚钱的方法。 在网络上面其实有很多的赚钱方法,尽管方法很多,但是对于一些网络新手,刚进入互联网圈子不久的伙伴…

智慧校园建设的重要性有哪些

在21世纪的数字化浪潮中,教育领域正经历一场深刻的变革。智慧校园,这一概念如同一股清风,席卷全球的高等教育机构,以其创新的科技应用和教育理念,重塑着学习的未来。面对信息时代的挑战,传统校园模式是否还…

html+CSS部分基础运用9

项目1 参会注册表 1.设计参会注册表页面,效果如图9-1所示。 图9-1 参会注册表页面 项目2 设计《大学生暑期社会实践调查问卷》 1.设计“大学生暑期社会实践调查问卷”页面,如图9-2所示。 图9-2 大学生暑期社会调查表页面 2.调查表前导语的…

Win11有些exe双击后无反应的解决办法

现象 双击某些exe文件之后,小圆圈转了两下之后就消失,然后没任何反应。用回车反复启动也是一样的现象。 由于截图没法截图到鼠标,所以没法放出截图。 我电脑出现上述现象的软件有: 1.纸飞机调试助手 2.SOC Programming Tool 对…

3.4 移动机器人工作空间(摘自自主移动机器人导论2)

对于一个机器人来说,机动性等效于它的控制自由度。但是,机器人是处于某种环境的,因而下一个问题是把我们的分析放到环境之中。 我们关心机器人用它可控制的自由度在环境中定位它本身的方法。例如,考虑 Ackerman 车辆或汽车&#…

Docker容器快速入门(1)

目录 1.Docker 简介 2.跟普通虚拟机的对比 2.打包、分发、部署 Docker主要理念:一次封装(打包)随处运行(部署) 4.Docker 部署的优势 5.Docker 通常用来做什么 6.重要概念:镜像、容器、仓库 Docker 官方…

使用ssh连接ubuntu

一、下载连接工具 常见的连接工具右fianlshell、xshell等等。在本文章中使用的finalshell,工具可以去官网上下载,官网下载。 二、Ubuntu中配置shh 1、使用下面指令更新软件包(常用于下载安装或更新软件时使用,更新到最新的安装…

红苹果的圆度、直径大小标定

function fruitImageProcessingGUI% 创建主窗口和控件mainFigure figure(Units, normalized, Position, [0.3, 0.3, 0.4, 0.4]);instructionText uicontrol(Style, text, String, 请点击按钮执行相应的图像处理步骤, ...Units, normalized, Position, [0.1, 0.7, 0.8, 0.2], …

母亲的爱与妻子的爱,同为“爱“。不同感受!

母亲的爱与妻子的爱,虽然都是一个女人给予男人的爱,却有着本质的不同! 天下父母对儿女的爱大多相同。在母亲眼中,儿女无论是多大年龄,无论你是否长大成人,也无论你做多大的官,有多么大的成就&am…

HBuilderX新增uni-app项目并发布到微信小程序

目录 1、下载软件并安装 2、创建项目并配置小程序id 3、微信开发者工具运行项目并配置 4、开发一个登录页面并发布 5、上传代码并小程序打开 6、手机扫码查看小程序 7、体验完后还要发版要去小程序申请备案认证 1、下载软件并安装 下载HBuilderX 下载微信开发者工具 …

【Java SE】超详细讲解String类

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 初步认识String2. String类的常用方法2.1 字符串构造2.2 String对象比较2.2.1 比较是否引用同一个对象2.2…

【Pandas】深入解析`pd.read_json()`函数

【Pandas】深入解析pd.read_json()函数 🌈 欢迎莅临我的个人主页👈这里是我深耕Python编程、机器学习和自然语言处理(NLP)领域,并乐于分享知识与经验的小天地!🎇 🎓 博主简介&#x…