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

激光甲烷传感器DIY指南:从DFB激光器选型到Herriott池光路搭建

本文详细介绍了如何DIY激光甲烷传感器,从DFB激光器选型到Herriott池光路搭建的全过程。通过TDLAS技术实现ppm级甲烷检测,适用于家用燃气泄漏监测和农业沼气监测等场景。文章包含核心器件选型、光路搭建技巧、信号调理方案及系统集成优化,为创客提供实用指南。

f9g0h的博客 594

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

NOIP2008年普及组初赛题目答案及解析

NOIP2008年初赛详细题解

城南蝈蝈 926

Python爬虫实战:避开巨潮资讯网反爬,稳定获取上市公司年报PDF下载地址

本文详细介绍了如何使用Python和Selenium突破巨潮资讯网的动态加载限制,稳定获取上市公司年报PDF下载地址。通过模拟真实用户操作、智能等待策略和反反爬虫技巧,帮助开发者高效爬取财经数据,适用于股票代码查询和年报分析等场景。

weixin_29065659的博客 1666

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

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

八零点点 790

深入浅出DDR系列(二)--DDR工作原理

学习完了DDR的基本组成和硬件结构原理之后,从整体上了解了DDR的特性和静态图,包括原理、管脚图等。那么本章就要从动态的角度来分析时序结构,包括read/write的整个过程到数据返回发生了什么,其中包括以下内容 DDR是如何完成Read、Write 等的操作 DDR的基本命令 DDR的时序参数 DDR的性能分析 1. DRAM基本组成 对于DRAM,其主要由行和列组成,每一个bit中都是由类似右下图的类晶体管的结构组成,对于sdram的数据,可以通过控制column和row就可以访问sd

奇小葩 3万+

Delphi 序列化

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

kevinzhaoyp 2118

Python、Selenium实现问卷星自动填写(内含适配个人问卷的方法)

使用Python、Selenium实现问卷星自动填写,内含适配个人问卷的方法。

DaenCode的博客 3837

华为OD机考双机位C卷 - 打印机队列 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 打印机队列

算法大师! 4619

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

道路施工检测 (construction) - 基于Mapillary Vistas数据集的YOLOv11目标检测及UI界面实现

目标检测是计算机视觉的重要任务,目标是识别图像中的目标物体类别及其位置(用边界框表示)。两阶段检测器:如Faster R-CNN,准确度高但速度较慢单阶段检测器:如YOLO系列、SSD,速度快且精度相对较好,适合实时场景数据量:约25,000张高分辨率街景图标注类型:语义分割、实例分割、多类别检测类别示例:construction, road, car, person, traffic sign等格式:COCO风格JSON标注。

YOLO 496

序列化和反序列化

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

Rae8023的博客 399

【AUTOSAR SystemServices】深入解析StbM模块:功能定义、工作原理与代码实现

STBM模块:AUTOSAR同步时基管理核心解析 STBM(同步时基管理器)是AUTOSAR标准中实现车载系统时间同步的关键模块,主要功能包括: 时间基准管理:支持全局时基、偏移时基和纯本地时基三种类型,通过StbM_SetGlobalTime和StbM_SetOffset实现主从节点同步。 校正机制:采用偏移校正和速率校正算法(PPM级精度)补偿时钟偏差,确保多ECU时间一致性。 事件处理:监控时间跳变和超时事件,通过回调机制通知上层应用。 典型应用:用于CAN/Ethernet总线同步、时间触发调度及诊

1459

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

delphi对象序列化

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

javatoyou 307

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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也具有很大参考价值

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

余额充值