字节对齐(C++,C#)
C#字节对齐示例
结构体定义
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)],这是C#引用非托管的C/C++的DLL的一种定义定义结构体的方式,主要是为了内存中排序,LayoutKind有两个属性Sequential和Explicit,Sequential表示顺序存储,结构体内数据在内存中都是顺序存放的,CharSet=CharSet.Ansi表示编码方式。这都是为了使用非托管的指针准备的,这两点大家记住就可以。
Pack = 1 这个特性,它代表了结构体的字节对齐方式,在实际开发中,C++开发环境开始默认是2字节对齐方式 ,拿上面报文包头结构体为例,char类型在虽然在内存中至占用一个字节,但在结构体转为字节数组时,系统会自动补齐两个字节,所以如果C#这面定义为Pack=1,C++默认为2字节对齐的话,双方结构体会出现长度不一致的情况,相互转换时必然会发生错位,所以需要大家都默认1字节对齐的方式,C#定义Pack=1,C++ 添加 #pragma pack 1,保证结构体中字节对齐方式一致。
数组的定义,结构体中每个成员的长度都是需要明确的,因为内存需要根据这个分配空间,而C#结构体中数组是无法进行初始化的,这里我们需要在成员声明时进行定义;
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi,Pack = 1)]
public struct PackHeader
{public ushort packFlag;public ushort packlen;public ushort version;public ushort index;
}[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack = 1)]
public struct SendHeader
{public byte packFlag;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public byte[] space; // 数组,指定长度public ushort beflen;
}
byte[] 转结构体
using System.Runtime.InteropServices; // 引入命名空间
/// <summary>
/// 解析数据结构体
/// </summary>
/// <param name="buf"></param>
/// <param name="len"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object BytesToStruct(byte[] buf, int len, Type type)
{object rtn;try{IntPtr buffer = Marshal.AllocHGlobal(len);Marshal.Copy(buf, 0, buffer, len);rtn = Marshal.PtrToStructure(buffer, type);Marshal.FreeHGlobal(buffer);return rtn;}catch (Exception){return null;}
}
结构体转byte[]
<summary>
/// 结构体转byte数组
/// </summary>
/// <param name="structObj">要转换的结构体</param>
/// <returns>转换后的byte数组</returns>
public static byte[] StructToBytes(object structObj)
{//得到结构体的大小int size = Marshal.SizeOf(structObj);//创建byte数组byte[] bytes = new byte[size];//分配结构体大小的内存空间IntPtr structPtr = Marshal.AllocHGlobal(size);//将结构体拷到分配好的内存空间Marshal.StructureToPtr(structObj, structPtr, false);//从内存空间拷到byte数组Marshal.Copy(structPtr, bytes, 0, size);//释放内存空间Marshal.FreeHGlobal(structPtr);//返回byte数组return bytes;
}
C++ 字节对齐
字节对齐的好处:加快变量在内存的存取速度。
VS, VC等编译器默认是#pragma pack(8)常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐。
结构体的每个成员相对于结构体的首地址的偏移量,都是基本成员大小的整数倍。比如
struct{int a; //4 首地址&achar b; //1 第二个成员&b相对于第一个成员&a是整数倍double c; //8
}
常用对齐pragma pack(1)方式与数据解析
字节对齐常用的是数据解析与数据封装;pragma pack(1)是最常用的对齐方式之一。
#pragma once
#pragma pack(1)
typedef struct{unsigned short headerFlag;unsigned short len;unsigned char cmd;
} DataHeader,*PDataHeader;typedef struct{unsigned short val;
} DataHeart,*PDataHeart;typedef struct {unsigned char cmdNo;unsigned short timeSpan;unsigned char spaces[6];
}DataCmd, *PDataCmd;
#pragam pack()struct DataProtocUtils{// 解包示例bool ParseData(const char * buf,int len,int & cmdNo){PDataHeader pheader;PDataCmd = cmd;pheader = (PDataHeader)buf;if(pheader->cmd == 0x01){cmd = (PDataCmd)(buf+sizeof(DataHeader));cmdNo = cmd->cmdNo;return true;}return false;}// 封包示例bool PackHeartToHost(unsigned short state,char * buf,int & len){DataHeader header;header.headerFlag = 0x3A3A;header.cmd = 0x32;header.len = 1+sizeof(DataHeart); // len 不包括headerFlag、len、tail的长度;// 协议定义时一定要说明,否则会造成歧义DataHeart heart;heart.val = state;char tail[2] = {0xA3A3,0xA3A3}; // 包尾memcpy(buf,(char *)(&header),sizeof(DataHeader));len +=sizeof(DataHeader);memcpy(buf+leb,(char *)(&heart),sizeof(DataHeart));len +=sizeof(DataHeart);memcpy(buf+leb,tail,2); len+=2;return true;}
}
相关文章:
字节对齐(C++,C#)
C#字节对齐示例 结构体定义 [StructLayoutAttribute(LayoutKind.Sequential, CharSet CharSet.Ansi, Pack 1)],这是C#引用非托管的C/C的DLL的一种定义定义结构体的方式,主要是为了内存中排序,LayoutKind有两个属性Sequential和Explicit&a…...
使用mybatisplus查询sql时,报Error attempting to get column ‘ID‘ from result set错误
问题描述: 在使用如下代码进行查询时,报Error attempting to get column ‘ID’ from result set错误: LambdaQueryWrapper<TimeFeature> wrapper new LambdaQueryWrapper<>();wrapper.eq(TimeFeature::getDate, currentDateTim…...
ElementUI浅尝辄止32:NavMenu 导航菜单
为网站提供导航功能的菜单。常用于网站平台顶部或侧边栏菜单导航。 1.如何使用?顶栏 /*导航菜单默认为垂直模式,通过mode属性可以使导航菜单变更为水平模式。另外,在菜单中通过submenu组件可以生成二级菜单。Menu 还提供了background-color、…...
@Value的注入与静态注入 与 组件中静态工具类的注入
一、Value 的注入 首先时一般的注入,例如你的配置文件中: vod: access-key: 123456那么,你就可以在你的方法中进行注入: Component public class VodService{Value("${vod.access-key}")private String accessKey; }…...

Qt--自定义搜索控件,QLineEdit带前缀图标
写在前面 这里自定义一个搜索控件,通过自定义LineEdit的textChange信号,搜索指定内容,并以QCheckBox的方式显示在QListWidget中。 开发版本 Qt: 5.15.2 Qt: Creator10.0.2 编译环境:msvc2019_64bit release 效果 代码 自定义…...
8月AI实战:工业视觉缺陷检测
8月AI实战:工业视觉缺陷检测 –基于tflite的yolov8模型优化和推理 操作视频见B站连接:aidlux模型优化工业缺陷检测~~完美用我的华为手机实现缺陷检测的推理bilibiliaidlux模型优化工业缺陷检测~~完美用我…...
Kubernetes的ExternalName详解
ExternalName类型的Service在Kubernetes中用于将外部服务(不是Kubernetes集群内的服务)映射到Kubernetes集群内的Service。 样例 其创建方法如下: kind: Service apiVersion: v1 metadata:name: my-external-servicenamespace: cv-console…...
使用 Pandera 的 PySpark 应用程序的数据验证
推荐:使用 NSDT场景编辑器 快速搭建3D应用场景 本文简要介绍了 Pandera 的主要功能,然后继续解释 Pandera 数据验证如何与自最新版本 (Pandera 0.16.0) 以来使用本机 PySpark SQL 的数据处理工作流集成。 Pandera 旨在与其他流行…...

README
一、Markdown 简介 Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。 应用 当前许多网站都广泛使用 Markdown 来撰写帮助文档或是用于论坛上发表消息。例如:GitHub、简书、知乎等 编辑器 推荐使用Typora,官…...

Excel周报制作
Excel周报制作 文章目录 Excel周报制作一、理解数据二、数据透视表三、常用函数1.sum-求和2.sumif-单条件求和3.sumifs-多条件求和4.sum和subtotal的区别5.if函数6.if嵌套7.vlookup函数和数据透视表聚合8.index和match函数 四、周报开发五、报表总览 一、理解数据 这是一个线上…...
Qt QtCreator 所有官方下载地址
Qt QtCreator 所有版本官方下载地址 1.所有版本QT下载地址 : Index of /archive/qt 所有Qt Creator下载地址: Index of /archive/qtcreator 所有Qt VS开发插件下载地址: Index of /archive/vsaddin 4.Qt官网镜像下载地址: Index of /…...

C++包含整数各位重组
void 包含整数各位重组() {//缘由https://bbs.csdn.net/topics/395402016int shu 100000, bs 4, bi shu * bs, a 0, p 0, d 0;while (shu < 500000)if (a<6 && (p to_string(shu).find(to_string(bi)[a], p)) ! string::npos && (d to_string(bi…...
数学建模--模型总结(5)
优化问题: 线性规划,半定规划、几何规划、非线性规划,整数规划,多目标规划(分层序列法),最优控制(结合微分方程组)、变分法、动态规划,存贮论、代理模型、响…...

JavaScript 中的原型到底该如何理解?
JavaScript作为一个基于原型的OOP,和我们熟知的基于类的面向对象编程语言有很大的差异。如果不理解其中的本质含义,则无法深入理解JavaScript的诸多特性,以及由此产生的诸多“坑”。在讨论“原型”的概念之前,我们先来讨论一下“类…...

【MySQL基础】事务隔离03
目录 隔离性与隔离级别事务隔离的实现事务的启动方式MySQL事务代码示例 在MySQL中,事务支持是在引擎层实现的。MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAM 被 Inn…...
2023高教社杯数学建模C题思路分析 - 蔬菜类商品的自动定价与补货决策
# 1 赛题 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此, 商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销售的蔬菜…...

【MySQL】初见数据库
目录 什么是MySQL 为什么要使用数据库 数据库基础 数据库的本质 存储引擎 常用操作 登录mysql 创建数据库 使用数据库 查看数据库 创建数据库表 查看表 向表中插入数据 查询表中数据 什么是MySQL 🍒在我们服务器安装完 MySQL 服务之后,经…...
选择合适的帧率和分辨率:优化RTSP流视频抓取(java)
引言 在实时视频流应用中,选择适当的帧率和分辨率对于确保视频流的顺畅播放和图像质量至关重要。本文将向您介绍如何使用Java和JavaCV库中的FFmpegFrameGrabber来从RTSP流中抓取图像,并在抓取时设置帧率和分辨率。 一、配置开发环境 首先,…...
HTTP协议都有哪些方法?
分析&回答 HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法描述HEAD请求资源的头部信息, 并且这些头部与 HTTP GET 方法请求时返回的一致. 该请求方法的一个使用场景是在…...

数学建模--非整数规划求解的Python实现
目录 1.算法流程简介 2.算法核心代码 3.算法效果展示 1.算法流程简介 #非线性规划模型求解: #我们采用通用的minimize函数来求解 #minimize(f,x,method,bounds,contrains) #f是待求函数 #x是代求的自变量 #method是求解方法 #bounds是取值范围边界 #contrains是约束条件 &q…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...