[英]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.