Kotlin:编码和解码二进制结构数据(Kotlin 相当于 Python 的 struct.pack 和 struct.unpack)
对于基于 C 的嵌入式硬件模块,配置结构由特定布局中的多个字段组成,例如以这个 8 字节结构为例:
Offset | Datatype | Field |
---|---|---|
0 | UInt8 | fieldA |
1 | UInt16 | some_value |
3 | UInt32 | another_value |
7 | UInt8 | aByte |
This 8-字节配置可以通过 NFC 通信读取和写入。因此,有一个 Android 应用程序可以读取此数据(作为 8 个字节的序列)并将其写回,以便嵌入式硬件模块上的固件(用 C 编写)可以“理解”它。
现在的任务是将例如 12 ab cd 04 fe ff 56 77
(little-endian!)的 8 字节序列解码为解码值:
字段 | 要解码的 | 字节已解码的人类可读数字 |
---|---|---|
fieldA | 12 | 0x12 |
some_value | ab cd | 0xCDAB |
another_value | 04 fe ff 56 | 0x56FFFE04 |
aByte | 77 | 0x77 |
请注意,这是一个 Kotlin 或 Java 问题,不是 C 问题;)
现在我的问题是找到一种 Kotlin 方法来将这样的二进制结构解码为相应的值(如上所示),以便可以将这些值呈现给应用程序用户。并且,将这些值(在用户编辑一些值之后)编码回 8 字节的二进制结构。
请注意,字节顺序也是一个问题。一般来说,目标系统是小端ARM,Android应用程序也在小端系统上运行,所以可能没有问题。不过,这是巧合,我想明确指出这一点。
使用必要的显式字节序转换将数字解码/编码为此类字节的 Kotlin 方式是什么?
如果是针对 Python,则 struct
库及其 pack
和 unpack
函数对于此类任务来说是完美。但如何在 Kotlin 中做到这一点呢?我很想看到这样的功能......
For a C based embedded hardware module, the configuration structure is made up of several fields in a particular layout, e.g. take this 8-byte struct for example:
Offset | Datatype | Field |
---|---|---|
0 | UInt8 | fieldA |
1 | UInt16 | some_value |
3 | UInt32 | another_value |
7 | UInt8 | aByte |
This 8-byte config can be read and written via NFC communication. So there is an Android app which reads this data (as a sequence of 8 bytes) and can write it back, so that the firmware on the embedded hardware module (written in C) can "understand" it.
The task is now to decode the 8-byte sequence of e.g. 12 ab cd 04 fe ff 56 77
(little-endian!) into the decoded values:
Field | Bytes to be decoded | Decoded, human-readable number |
---|---|---|
fieldA | 12 | 0x12 |
some_value | ab cd | 0xCDAB |
another_value | 04 fe ff 56 | 0x56FFFE04 |
aByte | 77 | 0x77 |
Note that this is a Kotlin or Java question, no C question ;)
Now my question is about finding a Kotlin way to decode such a binary struct into the respective values (as shown above), so that the values can be presented to the app user. And, encode the values (after the user would have edited some values) back into the binary structure of 8 bytes.
Note that endianness is also an issue. In general, the target system is a little-endianed ARM and the Android app also runs on a little-endian system, so there might be no issue. However, this is by coincidence, and I would like to make this explicit.
What could be a Kotlin way of decoding/encoding numbers into such bytes, using explicit endian conversion of necessary?
If it was for Python, the struct
library with its pack
and unpack
function are PERFECT for such tasks. But how to do this in Kotlin? I would love to see exactly such functions ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我能想到的最好的方法是将字节数组包装在
ByteBuffer
并一一读取。假设您有:
您可以执行以下操作:
请注意,
ByteBuffer
的get
和getXXX
方法会提前“读取”位置,从而改变ByteBuffer
,因此,如果您在创建SomeStructure
后出于某种原因想要再次重新读取缓冲区,您应该翻转
它,或者只是创建一个新的字节缓冲区。您还可以将其设为
SomeStructure
的辅助构造函数。这样,您甚至可以支持从字节缓冲区读取引用
SomeStructure
的数据类:The best I can think of is to just wrap the byte array in a
ByteBuffer
and read it one by one.Suppose you have:
You can do:
Note that the
get
andgetXXX
methods ofByteBuffer
advances the "reading" position, hence mutating theByteBuffer
, so if you want to re-read the buffer again for whatever reason after creating theSomeStructure
, you shouldflip
it, or just create a new byte buffer.You could also make this a secondary constructor of
SomeStructure
.This way, you could even support reading data classes with references to
SomeStructure
s from byte buffers: