Delphi 结构体序列化为二进制串

JSON序列化反序列化带List delphi JSON序列化反序列化带List 立即下载

需求

有时候需要把结构体的数据变成二进制串。比如一堆数据最后需要从网络传输出去。当然,对应的需求就是从二进制串变回结构体。

实现

常见办法

比较常见的办法是直接把结构体内存数据复制到二进制串的变量所指向的内存位置。例子代码如下:

TMyRecord = packed record
    MyName: string[6];
    MySize: Integer;
  end;


var
  R, Ra: TMyRecord;
  B1: TBytes;
begin
  R.MyName := 'abcxyz';
  R.MySize := 343;

  SetLength(B1, SizeOf(R));
  Move(R, B1[0], SizeOf(R));

  //再变回来

  Move(B1[0], Ra, SizeOf(Ra));  
end;

Delphi 的一个比较著名的控件 Indy 就是这样干的。请看它的代码:

function RawToBytes(const AValue; const ASize: Integer): TIdBytes;
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
  SetLength(Result, ASize);
  if ASize > 0 then begin
    Move(AValue, Result[0], ASize);
  end;
end;


procedure BytesToRaw(const AValue: TIdBytes; var VBuffer; const ASize: Integer);
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
  Assert(Length(AValue) >= ASize);
  Move(AValue[0], VBuffer, ASize);
end;

就是有两个变量,分别有自己的内存空间,使用 Move 方法把数据复制过去。

但是,复制数据是需要消耗 CPU 资源的。如果需要复制的数据很多,就会影响程序执行效率。

那么,我们不复制数据,直接使用指针,如何?

使用指针

Delphi 是强类型语言,最好不要使用通用指针,而是使用类型指针。因此我们需要先定义一下数据类型。代码:

TMyRecord = packed record
    MyName: string[6];
    MySize: Integer;
  end;

  PMyRecord = ^TMyRecord;

  TMyArr = array[0..10] of Byte;
  PMyArr = ^TMyArr;

在上述的数据类型基础上,我写了一段测试代码,执行成功。

procedure TForm1.Button4Click(Sender: TObject);
var
  B, B1: TMyArr;
  R: TMyRecord;
  Rx: PMyRecord;
begin
  //这样直接操作指针是成功的!
  R.MyName := 'abcxyz';
  R.MySize := 222;


  B := TMyArr(R);
  Move(B[0], B1[0], SizeOf(R));

  Rx := PMyRecord(@(B1[0]));
  Log(Rx^.MyName);
  Log(Rx^.MySize.ToString);
end;

解释一下:

上述代码的 R 是一个结构体,B 是 Byte 数组。直接类型转换 R 为 B,实际上就是把 R 的指针地址给了 B;

后面的 Move 是为了验证把 B 的数据复制到 B1 里面,是否成功;

最后,Rx 是结构体指针,把 B1 的地址给 Rx,我们获得了结构体 Rx。因为 Rx 是指针,所以最后访问 Rx 的内容时,后面加上了那个 ^ 符号,这个是 Delphi 语法。

总结:

结构体和 Byte 数组之间,可以直接通过指针的方式做类型转换,不同的数据类型的变量,实际上都是指向同一个内存块。这样避免了数据复制,程序更少消耗 CPU。

delphi BaseObject_json序列化反序列化json模式都可以没有那个元素 立即下载

相关推荐

Delphi LiveBinding对象及对象序列化为JSON的例子

在Delphi里将对象和界面用LiveBinding方式绑定,用户操作界面改变对象属性值,对象属性值序列化为JSON字符串保存。

DELPHI XE2 采用 JSON 的方式来序列化对象

DELPHI XE2 采用 JSON 的方式来序列化对象 以下代码测试通过。问题是里面的中文,在反序列化后是乱码。  1. 序列化对象为字符串,Subject 里面的中文看起来正常,仍然是中文; 2. 反序列化为对象后,Subject 里面的中文是乱码。 XE2 处理 Unicode 还是有问题啊。 TItemRecord

yeeonefx的专栏 5713

高效低功耗设计:PMOS电子开关在墨水屏与ADC采样电路中的创新应用

本文深入探讨了PMOS电子开关在低功耗设计中的创新应用,特别是在墨水屏和ADC采样电路中的关键作用。通过详细分析PMOS的导通机制和近乎零静态功耗特性,展示了其在待机低功耗场景下的显著优势,并提供了实用的电路设计技巧和元器件选型建议,帮助工程师实现极致的功耗优化。

weixin_29193359的博客 162

delphi 二进制 八进制 十进制 十六进制 进制转换

<br />unit Unit2;<br /><br /><br />interface<br />uses<br />SysUtils,Math;<br />type<br />TConversion = class<br />public<br />    //10 进制 to 2,8,16 进制<br />    function inttoBitStr(intstr: string): string;<br />    function IntToHexStr(intStr: string): St

bavt0502的专栏 950

解锁 STP 与 SOLIDWORKS 转换密码:工具及迪威在线转换秘籍

STP 文件能够完整地记录 3D 模型的几何形状、尺寸、公差、材料属性等丰富信息,无论是简单的机械零件,还是复杂的装配体,都能精准呈现。而在线转换以迪威模型为例,凭借便捷性、高效性和安全性,为广大 3D 专业技术人员和学生党在无需安装额外软件的情况下,轻松实现格式转换提供了有力支持。在实际工作和学习中,可根据自身具体情况灵活选择合适的转换方式,以确保 3D 设计工作流程的顺畅进行,让创意在不同格式间自由流动并绽放光彩。在 3D 设计与建模的广袤世界里,不同格式文件间的转换常常是连接创意与实现的关键桥梁。

技术说明博主 3444

避坑指南:SAP CO模块维护成本控制范围的5个常见错误及解决方法

本文深入剖析了SAP CO模块中维护成本控制范围时最易犯的5个常见错误,包括货币参数配置不当、标准层次结构缺失、财政年度变式不一致、功能激活遗漏及集成参数设置错误。重点针对事务码OKKP的配置,提供了详细的排查步骤与实战解决方案,帮助顾问有效规避陷阱,确保成本核算体系稳定运行。

stone的博客 233

 Record的序列化和反序列化 (delphi)

Record的序列化和反序列化 TDefaultMessage = record //网络包头 Ident: Integer; nIsZlib: Integer; nLength: Integer; end; //记录转字符串 function RecordToString(var Buf; bufSize: Integer; isZlib: Boole...

八零点点 790

选课系统进不去?我用 Python 做了个“捡漏挂机”脚本,全自动监控空余名额

频率控制:脚本请求频率不要太高(建议间隔 3-5 秒以上),否则可能被教务系统封 IP,甚至会被教务处请喝茶。仅供学习:本文旨在通过选课场景教学requests和网络抓包原理,请勿用于非法用途或破坏公平性。刷新页面 -> 等待加载 -> 用眼睛看人数 -> 没满?-> 点击选课 -> 确认这个流程最大的瓶颈在于**“等待加载”和“人的反应时间”**。网页加载需要渲染 HTML、CSS、图片,而 Python 脚本只需要请求一个微小的 JSON 数据接口,速度是浏览器的10 倍以上。fill:#333;

BUG猿的博客 292

Delphi 序列化

Delphi中序列化的方法。 读:function TStream.ReadComponentRes(Instance: TComponent): TComponent;写:procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent);本想用序列化实现语言切换,可发现序列化后的文件跟乱码一样。不知

kevinzhaoyp 2118

MATLAB代码实现了船舶航线优化的功能,使用混合遗传算法(结合模拟退火算法)来寻找从大连港到格拉斯通港的最优航线,同时考虑了船舶的参数、气象数据(风速、风向、有效波高、波浪阻力系数等)对航行的影响

这段MATLAB代码主要实现了船舶航线优化的功能,使用混合遗传算法(结合模拟退火算法)来寻找从大连港到格拉斯通港的最优航线,同时考虑了船舶的参数、气象数据(风速、风向、有效波高、波浪阻力系数等)对航行的影响。通过以上步骤,该代码能够找到一条在考虑船舶性能和气象条件下,从大连港到格拉斯通港的较优航线,最小化燃油消耗和航行时间的加权和。

AI的内部世界的博客 513

TI单芯片毫米波雷达1642demo代码走读(一)

今天我们来实际看下代码。 首先使用CCS软件导入demo工程,工程有两个,一个是ARM的工程,工程名是mmw_mss_16xx;另一个是DSP的工程,工程名为mmw_dss_16xx。我们将这两个工程的主函数打开,分别位于mss_main.c和dss_main.c文件中。 先看mss的主函数,代码如下。我为每行代码都加了中文注释和自己的理解。 int main (void) { Task_Params taskPara...

1万+

delphi 序列化

procedure TFrmMain.btn_readClick(Sender: TObject); var ts: TStream; i: integer; lpath: string; begin //反序列化 lpath := ExtractFilePath(ParamStr(0)); ts := TFileStream.Create(lpath + 'serialization.txt', fmOpenRead); for i := 0 to Self.Componen.

全粘工程师 646

Python实现商品价格监控与波动分析爬虫项目

本文通过完整的代码示例和详细的技术讲解,展示了如何实现商品价格的自动监控和波动分析。该项目不仅适用于个人购物助手,还可以扩展为商家的竞品监控工具。通过结合数据抓取、存储、分析与可视化,能够帮助我们更好地理解市场趋势并做出优化决策。

2201_76125261的博客 1743

序列化和反序列化

什么是序列化和反序列化? 把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象–这两个功能就是序列化和反序列化。 序列化:把对象转换为字节序列的过程称为对象的序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化 数据结构、对象与二进制串 不同的计算机语言中,数据结构,对象以及二进制串的表示方式并不相同。 数据结构和对象:对于类似Java这种...

Rae8023的博客 399

使用菱FX5U系列PLC实现以太网通信的具体方法示例

接下来,我们将创建一个简单的CPU通信功能,以实现与其他设备的以太网通信。在上述代码中,我们首先设置访问号,然后创建一个数据读取命令(M_READ)和一个数据写入命令(M_WRITE)。此外,在实际应用中,您还需要确保PLC和其他设备之间的网络连接正常,并且遵循相应的通信协议。在上述代码中,我们执行了数据读取命令,并将接收到的响应存储在M_RESPONSE变量中。通过简单CPU通信功能,菱FX5U系列PLC可以实现与其他设备的以太网通信。我们将提供相应的源代码和详细的说明,以帮助您轻松实现这一功能。

DevCyberX的博客 1526

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

delphi对象序列化

functionComponentToStr(AComponent:TComponent):string;varBinStream:TMemoryStream;StrStream:TStringStream;s:string;beginBinStream:=TMemoryStream.Create;tryStrStream:=TStringStream.Create(s);tryBinStream...

javatoyou 307

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Delphi进制转换(二进制/十进制/十六进制)

Delphi进制转换(二进制/十进制/十六进制)  2009-11-27 11:42:24|  分类: 计算机知识 |  标签: |字号大中小 订阅 . Delphi进制转换(二进制/十进制/十六进制) 2008-08-29 10:24   一、完全用API完成:..uses Windows; function IntToStr(I: integer): string; begin ...

weixin_33935777的博客 577

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

delphi序列化对象的方法总结

1.组件对象的序列化从TCOMPONENT继承下来的组件对象序列化都简单,因为它本身支持流化,通过流化也就达到了序列化组件对象的目的。TReader和TWriter都只支持Tcomponent流化,除非你自己写个TReader和TWriter,就有可能支持TPersiten的流化. function   ComponentToString(Component:   TComponent):   string; var     BinStream:TMemoryStream;     StrStream:  

1824

delphi 用record结构读取记录文件的问题

type //曲线分析   TQxfx = record     TTName :  string[128];     ZName :   string[128];     Xl30150 : Real;     sjl30150 : Real;     xl150170 : Real;     sj150170 : Real;     hhxv  

坦然 3482

Delphi XE10 序列化 TDictionary 为 JSON 的问题

1. 在 XE10 里面,对 TObjectList 进行序列化为 JSON 的操作是成功的。大概代码如下,测试通过。 S := TJson.ObjectToJsonString(FMyObjectList); AObjectList := TJson.JsonToObject>(S); 2. 照上述方法,序列化一个 TDictionary 为字符串也成功。然后,

pcplayer的博客 2820

Delphi - 简单10进制转2进制的函数

技术交流,DH讲解. 昨晚半夜1点多,有个朋友来问这个问题.想了下,先打算偷懒,让他先用IntToHex转16进制,然后1位16进制对应4位二进制.后来想了下这样做,太不该了.于是自己随手写了个函数:我们只要对位运算熟悉就可以了,我们一位一位的去判断是0还是1就可以了.为了避免String引起的效率问题,我们直接用Array[0..31] of Char. Type TBinString...

weixin_33755649的博客 187
上一篇: Indy HTTP Server 使用 OpenSSL 3.0
下一篇: 显示 Markdown 的文件
pcplayer
博客等级 码龄26年 633粉丝 284原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值