当前位置: 首页 > 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…...

shell脚本--常见案例

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

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...