簡體   English   中英

在C和Delphi中將字節數組轉換為2個無符號長

[英]Converting an byte array into 2 unsigned long in C and Delphi

下面的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;
(byte *)&iONE)+sizeof(unsigned long)-4

正在嘗試從iONE讀取4個字節,但也考慮了unsigned long大於4個字節的可能性。 該代碼通過挑選iONE的最后4個字節來iONE 由於代碼始終從變量的同一端讀取,因此其行為在大小端機器之間有所不同。 在沒有任何上下文的情況下,很難說出這段代碼想要實現什么,但是我的猜測是,它最初運行在一個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;

但是,這將有助於更多地了解原始代碼。 就我個人而言,如果我面臨此任務,我會從頭開始編寫代碼,而不是編寫文字端口。 原始代碼看起來已經很差了,一旦翻譯完成,那就更糟了。 弄清楚代碼的作用,並使用目標語言的慣用法編寫新程序。

您的代碼有兩個小要點:

  1. 初始化立即被覆蓋的變量是沒有意義的。 這只會使未來的讀者感到困惑。
  2. CopyMemory是Windows API函數,因此不可移植。 System.Move是用於原始內存副本的功能。
memcpy(((byte *)&iONE)+sizeof(unsigned long)-4, temp, 4);

temp將4個字節復制到iONE的地址中,其偏移量為sizeof(unsigned long)-4 ,並且

memcpy((byte *)&iONE, temp, 4);

將在iONE存儲地址的開頭從temp復制4個字節。

所以sizeof(unsigned long)-4只是一個字節偏移量,從temp復制4個字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM