以下C代码:
typedef unsigned char byte;
byte temp[8] = {...};
unsigned long iONE = 0;
unsigned long iTWO = 0;
memcpy(((byte *)&iONE)+sizeof(unsigned long)-4, temp, 4);
memcpy(((byte *)&iTWO)+sizeof(unsigned long)-4, temp+4, 4);
+sizeof(unsigned long)-4
有什么意义?
memcpy
语句可以写成:
memcpy((byte *)&iONE, temp, 4);
memcpy((byte *)&iTWO, temp+4, 4);
并且Delphi转换有效:
var
temp: array[0..7] of Byte;
iONE: Cardinal;
iTWO: Cardinal;
begin
temp := ...;
iONE := 0;
iTWO := 0;
CopyMemory(iOne, temp[0], SizeOf(Cardinal));
CopyMemory(iTwo, temp[4], SizeOf(Cardinal));
end;
答案 0 :(得分:1)
(byte *)&iONE)+sizeof(unsigned long)-4
尝试从iONE
读取4个字节,但也考虑unsigned long
大于4个字节的可能性。代码通过摘下iONE
的最后4个字节来实现。由于代码总是从变量的同一端读取,因此它在小端和大端机器之间的行为会有所不同。没有任何上下文,很难说这段代码试图实现什么,但我猜测它最初是在一个8字节unsigned long
的大端系统上运行的。也许你知道更多。
在Delphi中你可能会这样写。
var
temp: array[0..7] of Byte;
iONE: Cardinal;
iTWO: Cardinal;
begin
temp := ...;
iONE := PCardinal(@temp[0])^;
iTWO := PCardinal(@temp[4])^;;
end;
但是,了解有关原始代码的更多信息会有所帮助。就个人而言,如果我遇到这个任务,我会从头开始编写代码,而不是创建一个文字端口。原始代码看起来很糟糕,一旦翻译完就会更糟。弄清楚代码的作用,并使用目标语言的惯用语编写新程序。
代码中的两个小问题:
CopyMemory
是Windows API函数,因此不可移植。 System.Move
是用于原始内存副本的函数。 答案 1 :(得分:0)
memcpy(((byte *)&iONE)+sizeof(unsigned long)-4, temp, 4);
将temp
的4个字节复制到偏移iONE
的{{1}}地址,
sizeof(unsigned long)-4
将从memcpy((byte *)&iONE, temp, 4);
处复制4个字节,该地址位于存储temp
的地址的开头。
所以iONE
只是一个以字节为单位的偏移量,可以从sizeof(unsigned long)-4
复制4个字节。