如何在 GO 中通过编码包打包 C 位字段结构?

How to pack the C bit field struct via encoding package in GO?

除了使用cgo,你知道将GO对象打包到byte slice的最佳方式是什么吗?

据我们所知,我们可以使用 encoding/binary 包将 GO 结构序列化为字节切片,但它仅支持定长变量,因此不支持以下情况。

typedef struct
{
    uint32_t          foo:12;
    uint32_t          bar:9;
    uint32_t          baz:1;
    uint32_t          qux:10;
} type_t;

对于这种情况,我们是否需要使用 getter/setter 实现 GO 结构,考虑到字节顺序,位操作非常糟糕? 如:

type typeT struct
{
    fooBarBazQux uint32
}
// some complex bit manipulation considering endianness
func (t typeT) getFoo() uint32 {
}
func (t typeT) setFoo(val uint32) {
}

有没有更好的解决方案?

我尝试 encoding/json mashaler 我的自定义类型,但 encoding/binary 包似乎不支持这种接口。

我需要你的帮助。

无法保证 C 中此类结构的实际打包和位顺序,并且可能因编译器而异,即使在同一台机器上也是如此。1 如果位顺序实际上很重要——在这种情况下很重要——你可能应该编写自己的 setter 和 getter。

Go 确实内置了 binary encoding operations,它可以让您访问二进制数据,即使它不是以本机机器顺序存储的。但是您可以对此类访问进行开放编码;它们不是特别复杂。同样,为插入和访问做所有的移位和屏蔽并不困难,只是有点乏味。

Cgo 不支持位域访问。相关(但没有答案):How to access C bitfield in Go; Go: Bitfields and bit packing(不支持 cgo 中的位域,none 计划)。


1过去,在 680x0 上,从 MIT C 编译器切换到 Sun 编译器时,这是一个问题,因为它们在字中使用不同的位顺序。当 68020 引入位域指令时,它们对位的编号与早期的单位测试指令不同,这在某种程度上助长了这种不兼容性。另见 Are later 68000 variants backward compatible with earlier ones?