簡體   English   中英

char *(數組)轉換為unsigned long + 1?

[英]char* (Array) cast to unsigned long + 1?

我正在嘗試將一些C代碼移植到Java,但是我一直在努力弄清楚這些代碼行的作用。

注意: rawEntry的類型為char*並且看起來像這樣分配了12個字節

char *rawEntry = (char*)malloc(0x000c);

unsigned long *l;
unsigned long offset;

// ...

l = (unsigned long*) rawEntry + 1;
offset = ntohl(*l);

據我所知,它需要數組的前四項,並將它們組合在一起形成一個長的,但是我在java中的嘗試並不成功。

offset = (rawEntry[0] << 24) +
         (rawEntry[1] << 16) +
         (rawEntry[2] << 8) +
         (rawEntry[3]) +
         1;

當出現以下數組時,

1 0 0 0 0 0 0 0 0 0 11 -38

C代碼輸出3034作為偏移
我的Java代碼輸出16777217,如果我翻轉endian,則輸出1

這個表達

l = (unsigned long*) rawEntry + 1;

rawEntry轉換為指向系統上大小為8字節的類型的指針。 之后,添加1表示添加8個字節,因此實際轉換如下所示:

offset = (Byte.toUnsignedInt(rawEntry[ 8]) << 24) +
         (Byte.toUnsignedInt(rawEntry[ 9]) << 16) +
         (Byte.toUnsignedInt(rawEntry[10]) <<  8) +
         (Byte.toUnsignedInt(rawEntry[11]) <<  0);

以下四個字節被解釋為3034

0 0 11 -38

您應該能夠通過使用ByteBuffer進一步簡化這一過程:

int offset = ByteBuffer.wrap(rawEntry, 8, 4).getInt();

在進一步說明之前,請務必注意此代碼取決於平台上long的實際大小。 在64位平台上,long是64位,這是一個long 8字節。 另一方面, ntohl轉換為32位長(4字節)的“網絡長”。

假設rawEntry{1,0,0,0,0,0,0,0,0,0,0xB,0xDA,…} (0xB是11的基數16,0xDA是基數16(十六進制) unsigned值對應-38)

l = (unsigned long*) rawEntry + 1;

真的意味着l指的是第二個unsigned long 這是從rawEntry跳過前8個字節然后l指向{0,0,0xB,0xDA,…}部分。 現在*l是由{0,0,0xB,0xDA,…}字節序列表示的unsigned long {0,0,0xB,0xDA,…}它取決於您的體系結構。 如果你在一個小的endian機器上將是0x ... DA0B0000(省略號,因為數組的末尾是未知的,這是未定義的行為)。 現在ntohl只保留最后32位並反轉字節順序,導致0x00000BDA或3034在基數10。

用Java編寫它的簡單方法是

offset = (rawEntry[8] << 24) +
         (rawEntry[9] << 16) +
         (rawEntry[10] << 8) +
         (rawEntry[11]);

暫無
暫無

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

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