繁体   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