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

需求

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

实现

常见办法

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

Delphi 复制代码
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 就是这样干的。请看它的代码:

Delphi 复制代码
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 是强类型语言,最好不要使用通用指针,而是使用类型指针。因此我们需要先定义一下数据类型。代码:

Delphi 复制代码
TMyRecord = packed record
    MyName: string[6];
    MySize: Integer;
  end;

  PMyRecord = ^TMyRecord;

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

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

Delphi 复制代码
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。

相关推荐
专注VB编程开发20年2 天前
delphi死嗑Pascal冷门编程语言,Borland不认可 “通用多语言 IDE”,认为 “专有语言才是护城河”
开发语言·ide·delphi
专注VB编程开发20年2 天前
Delphi 的VCL控件库无法公开给其他编程语言调用
开发语言·delphi
qqww15510 天前
DelphiSpeedUp 介绍
delphi
xyzhan15 天前
使用Delphi开发混凝土生产车间自动化过程控制系统的仿真系统
运维·物联网·自动化·delphi·仿真·混凝土车间
pcplayer2 个月前
Delphi程序和大模型交互之二
人工智能·ai·大模型·agent·delphi
xyzhan2 个月前
RAD Studio Amalthea Delphi 13.1 Beta深度解析:Delphi重磅更新,原生支持Windows ARM64EC
windows·delphi·rad studio·c++ builder·delphi 13
delphi 三层源码框架2 个月前
delphi发送SSL 465端口邮件
ssl·delphi·发送邮件·indy 465端口
tanqth5 个月前
Delphi跨平台开发中为Linux开发的优劣分析
跨平台·delphi·分析·linux开发
BillKu7 个月前
在 Delphi 5 中获取 Word 文档页数的方法
word·delphi