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

字节对齐(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)]&#xff0c;这是C#引用非托管的C/C的DLL的一种定义定义结构体的方式&#xff0c;主要是为了内存中排序&#xff0c;LayoutKind有两个属性Sequential和Explicit&a…...

使用mybatisplus查询sql时,报Error attempting to get column ‘ID‘ from result set错误

问题描述&#xff1a; 在使用如下代码进行查询时&#xff0c;报Error attempting to get column ‘ID’ from result set错误&#xff1a; LambdaQueryWrapper<TimeFeature> wrapper new LambdaQueryWrapper<>();wrapper.eq(TimeFeature::getDate, currentDateTim…...

ElementUI浅尝辄止32:NavMenu 导航菜单

为网站提供导航功能的菜单。常用于网站平台顶部或侧边栏菜单导航。 1.如何使用&#xff1f;顶栏 /*导航菜单默认为垂直模式&#xff0c;通过mode属性可以使导航菜单变更为水平模式。另外&#xff0c;在菜单中通过submenu组件可以生成二级菜单。Menu 还提供了background-color、…...

@Value的注入与静态注入 与 组件中静态工具类的注入

一、Value 的注入 首先时一般的注入&#xff0c;例如你的配置文件中&#xff1a; vod: access-key: 123456那么&#xff0c;你就可以在你的方法中进行注入&#xff1a; Component public class VodService{Value("${vod.access-key}")private String accessKey; }…...

Qt--自定义搜索控件,QLineEdit带前缀图标

写在前面 这里自定义一个搜索控件&#xff0c;通过自定义LineEdit的textChange信号&#xff0c;搜索指定内容&#xff0c;并以QCheckBox的方式显示在QListWidget中。 开发版本 Qt: 5.15.2 Qt: Creator10.0.2 编译环境&#xff1a;msvc2019_64bit release 效果 代码 自定义…...

8月AI实战:工业视觉缺陷检测

8月AI实战&#xff1a;工业视觉缺陷检测 –基于tflite的yolov8模型优化和推理 操作视频见B站连接&#xff1a;aidlux模型优化工业缺陷检测&#xff5e;&#xff5e;完美用我的华为手机实现缺陷检测的推理bilibiliaidlux模型优化工业缺陷检测&#xff5e;&#xff5e;完美用我…...

Kubernetes的ExternalName详解

ExternalName类型的Service在Kubernetes中用于将外部服务&#xff08;不是Kubernetes集群内的服务&#xff09;映射到Kubernetes集群内的Service。 样例 其创建方法如下&#xff1a; kind: Service apiVersion: v1 metadata:name: my-external-servicenamespace: cv-console…...

使用 Pandera 的 PySpark 应用程序的数据验证

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 本文简要介绍了 Pandera 的主要功能&#xff0c;然后继续解释 Pandera 数据验证如何与自最新版本 &#xff08;Pandera 0.16.0&#xff09; 以来使用本机 PySpark SQL 的数据处理工作流集成。 Pandera 旨在与其他流行…...

README

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

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下载地址 &#xff1a; Index of /archive/qt 所有Qt Creator下载地址&#xff1a; Index of /archive/qtcreator 所有Qt VS开发插件下载地址: Index of /archive/vsaddin 4.Qt官网镜像下载地址&#xff1a; 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)

优化问题&#xff1a; 线性规划&#xff0c;半定规划、几何规划、非线性规划&#xff0c;整数规划&#xff0c;多目标规划&#xff08;分层序列法&#xff09;&#xff0c;最优控制&#xff08;结合微分方程组&#xff09;、变分法、动态规划&#xff0c;存贮论、代理模型、响…...

JavaScript 中的原型到底该如何理解?

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

【MySQL基础】事务隔离03

目录 隔离性与隔离级别事务隔离的实现事务的启动方式MySQL事务代码示例 在MySQL中&#xff0c;事务支持是在引擎层实现的。MySQL是一个支持多引擎的系统&#xff0c;但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务&#xff0c;这也是 MyISAM 被 Inn…...

2023高教社杯数学建模C题思路分析 - 蔬菜类商品的自动定价与补货决策

# 1 赛题 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差&#xff0c; 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&#xff0c; 商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销售的蔬菜…...

【MySQL】初见数据库

目录 什么是MySQL 为什么要使用数据库 数据库基础 数据库的本质 存储引擎 常用操作 登录mysql 创建数据库 使用数据库 查看数据库 创建数据库表 查看表 向表中插入数据 查询表中数据 什么是MySQL &#x1f352;在我们服务器安装完 MySQL 服务之后&#xff0c;经…...

选择合适的帧率和分辨率:优化RTSP流视频抓取(java)

引言 在实时视频流应用中&#xff0c;选择适当的帧率和分辨率对于确保视频流的顺畅播放和图像质量至关重要。本文将向您介绍如何使用Java和JavaCV库中的FFmpegFrameGrabber来从RTSP流中抓取图像&#xff0c;并在抓取时设置帧率和分辨率。 一、配置开发环境 首先&#xff0c;…...

HTTP协议都有哪些方法?

分析&回答 HTTP1.0定义了三种请求方法&#xff1a; GET, POST 和 HEAD方法HTTP1.1新增了五种请求方法&#xff1a;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…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...