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

开发基于GDL235KBQ6开发板的IAP升级程序(HEX协议+串口空闲中断 + DMA接收数据)

使用GDL235kB开发板,实现串口iap升级程序的bootloader代码编写,app为led灯闪烁,并完成通信c代码

zhaozijuncc的博客 642

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

快速玩转 Llama2!机器学习 PAI 最佳实践(一)—低代码 Lora 微调及部署

本实践将采用阿里云机器学习平台PAI-快速开始模块针对 Llama-2-7b-chat 进行开发。PAI-快速开始支持基于开源模型的低代码训练、布署和推理全流程,适合想要快速开箱体验预训练模型的开发者。

阿里云云栖号 1766

自定义串口通讯协议

自定义串口通讯协议的实现方法

qq_44826038的博客 2172

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

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

八零点点 790

Win11下高效管理JDK1.8与JDK17双环境的实战指南

本文提供了一份在Windows 11系统上高效管理JDK 1.8与JDK 17双环境的实战指南。文章详细讲解了如何实现双版本切换,包括如何干净安装两个JDK、通过巧妙配置环境变量实现命令行一键切换,以及在不同IDE和构建工具中为项目独立配置JDK版本,旨在帮助Java开发者彻底解决版本冲突问题,提升开发效率。

ipfs8storage的博客 543

Delphi 序列化

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

kevinzhaoyp 2118

(详细总结)python爬取 163收件箱邮件内容,收件箱列表的几种方法(urllib, requests, selenium)

需求:最近有一个需求,需要将163邮箱收件箱里面的所有邮件的内容全部copy下来,整理到一个word里面,不多也就28页的邮件(不要问我为什么有这需求,不告诉你),自己手动去ctrl+ cv 的话,估计要搞吐。然后就想能不能用python的爬虫来实现,虽然过程比较苦(后期改bug改的要吐了)。但是会后还是将需求实现了。这基本也算是入门了 urllib、requests、selenium这几个py...

man_tou_22 1万+

ABAP Open SQL 数据拷贝导致 SAPSQL_DATA_LOSS:从报错机理到稳妥修复

数据类型与长度不合规。一旦在Open SQL的无损赋值检查里被发现,系统宁可中止也不会偷偷替你截断。把变量声明对齐到字典、在需要时明确表达转换/截断意图、写法上避免落入高危的操作数位置,再配合ATC的预防性检查,既能解决你这次的ST22Dump,也能把同类问题消灭在萌芽状态。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 429

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

【STM32Cube_14】使用硬件I2C读写环境光强度传感器(BH1750)

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设读取环境光强度传感器数据(BH1750)

Mculover666的博客(嵌入式) 7242

序列化和反序列化

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

Rae8023的博客 399

【具身智能】感知 × 决策 × 执行:一个智能体的认知闭环怎么搭?

构建一个真正能在现实世界中运作的具身智能体,并不是简单地拼接“视觉 + 控制器 + 动作模块”就能完成的,它必须是一个**认知闭环结构**:能感知环境、理解状态、制定策略、执行动作,并从结果中学习反馈。 本讲将深入剖析具身智能的三大核心支柱:**感知系统、决策系统、执行系统**,并解析它们如何协同构建出一个“能观察、能思考、能行动”的智能体。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3262

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

delphi对象序列化

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

javatoyou 307

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

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

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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、付费专栏及课程。

余额充值