这个Delphi PAnsiChar代码是什么意思?

时间:2017-05-18 16:24:33

标签: file delphi byte

我们都将Delphi用于一个项目并且已经有多年了。 但我们从未见过与PAnsiChar一起使用的以下语法,并且不知道它的含义:

buffer       : PAnsiChar
recInstance  : Byte
recX         : smallint
num_info     : integer

// buffer loaded from a file...

num_info := 0;
// next two lines are a mystery
recInstance := Byte(buffer[num_info*5]);
recX := Byte(buffer[num_info*5+1])+256*Byte(buffer[num_info*5+2]);

在调试器中看起来recX只是加载2个字节,但语法似乎不匹配。

2 个答案:

答案 0 :(得分:2)

PAnsiChar总是有一个很好的属性,你可以访问被指向的AnsiChar,以及下面的AnsiChar使用索引表示法,如数组(字节或{ {1}} S)。这就是为什么在这里使用它。

现在,在具有AnsiChar的现代版本中,您宁愿使用{$POINTERMATH},而是启用相同的索引。

PByte被赋予偏移量recInstance的字节,numinfo*5被分配以下两个字节作为一个单独的16位值。

在当前版本中,它可以写成:

recX

正如雷米暗示的那样,您可以使用以下方式一次读取所有三个字节:

buffer: PByte;
n: Integer;

...

n := num_info * 5;
recInstance := buffer[n];
recX := buffer[n+1] or (buffer[n+2] shl 8); // together a 16 bit value

type PRec = ^TRec; TRec = packed record Instance: Byte; X: Smallint; // a 16 bit (i.e. 2 byte) signed integer. end; // total size: 3 bytes. var MyRec: TRec; ... MyRec := PRec(@buffer[num_info * 5])^; 强制转换将PRec返回的地址重新解释为指向@buffer[num_info * 5]的指针,然后取消引用(使用TRec),并将结果分配给^

换句话说,MyRec是一个指针,@buffer[...]将其转换为PRec(...)类型的指针,PRec获取该指针的3个字节,就好像它一样是PRec(...)^

TRec现在与MyRec.X相同,recX现在与原始代码中的MyRec.Instance相同。

答案 1 :(得分:0)

Byte()只是将一个字节大小的值(此处为AnsiChar)类型转换为字节类型

最后一行代码行从两个字节形成双字节变量recX(不考虑可能的溢出效应)

 int16var = byte1 + 256 * byte2  
 //almost equivalent of
 (byte2 shl 8) or byte1