c++ 在Kotlin中处理endianess

yacmzcpb  于 2024-01-09  发布在  Kotlin
关注(0)|答案(1)|浏览(190)

我试图在Android应用程序中对字节数组进行格式化(在MacOS上使用M1芯片编译)。字节来自网络,由运行在Ubuntu上的C应用程序生成。在C应用程序中,我检查了它使用的是Little Endian:

  1. bool isBigEndian()
  2. {
  3. uint16_t word = 1; // 0x0001
  4. uint8_t *first_byte = (uint8_t *)&word; // points to the first byte of word
  5. return !(*first_byte); // true if the first byte is zero
  6. }
  7. // Check:
  8. if (isBigEndian())
  9. printf("Big endian\n");
  10. else
  11. printf("Little endian\n");

字符串
以上代码用C++打印出来Little endian
在Kotlin(Android)端,我也检查并看到它也使用了Little Endian,但从字节数组转换的长数字不正确。

  1. fun isLittleEndian(): Boolean {
  2. return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN
  3. }
  4. /**
  5. * Represent 8 bytes of [Long] into byte array
  6. */
  7. fun Long.toBytes(): ByteArray {
  8. return ByteBuffer.allocate(Long.SIZE_BYTES).putLong(this).array()
  9. }
  10. fun ByteArray.toLong(): Long {
  11. return ByteBuffer.wrap(this).long
  12. }
  13. fun test(){
  14. val longNumber = 1000L
  15. val isLittleEndian = isLittleEndian() // true
  16. val bytes = longNumber.toBytes() // bytes: [0,0,0,0,0,0,3,-24] => Big Endian?
  17. }


C应用程序将长数字1000序列化为[ -24, 3,0,0,0,0,0,0](正确的小端排序),而Kotlin代码将相同的长数字转换为[0,0,0,0,0,0,3,-24](这是大端排序)。
当使用Kotlin从C
应用程序转换字节时,我得到了奇怪的值-1728537831980138496而不是1000
请帮我检查一下我在处理endianess时有没有出错?

oyt4ldly

oyt4ldly1#

allocatewrap方法都将返回一个BIG_ENDIAN缓冲区。您必须调用order将字节序更改为LITTLE_ENDIAN
举例来说:

  1. import java.nio.ByteBuffer
  2. import java.nio.ByteOrder
  3. import java.nio.ByteOrder.BIG_ENDIAN
  4. import java.nio.ByteOrder.LITTLE_ENDIAN
  5. fun Long.toBytes(order: ByteOrder = BIG_ENDIAN): ByteArray {
  6. return ByteBuffer.allocate(Long.SIZE_BYTES).order(order).putLong(this).array()
  7. }
  8. fun ByteArray.toLong(order: ByteOrder = BIG_ENDIAN): Long {
  9. return ByteBuffer.wrap(this).order(order).long
  10. }
  11. fun main() {
  12. val number = 1000L
  13. val encoded = number.toBytes(order = LITTLE_ENDIAN)
  14. val decoded = encoded.toLong(order = LITTLE_ENDIAN)
  15. println("Number = $number")
  16. println("Encoded = ${encoded.contentToString()}")
  17. println("Decoded = $decoded")
  18. }

字符串
输出量:

  1. Number = 1000
  2. Encoded = [-24, 3, 0, 0, 0, 0, 0, 0]
  3. Decoded = 1000

展开查看全部

相关问题