【问题标题】:How to pack the C bit field struct via encoding package in GO?如何在 GO 中通过编码包打包 C 位字段结构?
【发布时间】:2020-02-12 03:49:48
【问题描述】:

除了使用 cgo,你知道将 GO 对象打包到字节切片的最佳方法是什么吗?

据我们所知,我们可以使用 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,但编码/二进制包似乎不支持这种接口。

我需要你的帮助。

【问题讨论】:

    标签: c go encoding bit bit-fields


    【解决方案1】:

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

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

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


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

    【讨论】:

      猜你喜欢
      • 2014-11-07
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      相关资源
      最近更新 更多