How to access C bitfield in Go

可紊 提交于 2020-08-27 12:45:34

问题


I have a struct like so:

typedef struct st_MASK_SETTINGS
{
  uint32_t foo  : 1;
  uint32_t bar  : 7;
} MASK_SETTINGS

Now through cgo I would like to access foo - but cannot find any documentation how to do so.

Naive v := ms.foo complains has no field or method.


回答1:


Well you won't like this answer, but

  1. there is no portable way to do this because bitfield packing is "implementation-defined" in both C and C++, and
  2. bitfield support in Go seems fairly crappy (perhaps due to #1).

First of all, the layout of bitfields is implementation-defined in every existing C and C++ standard. This means that none of the standards specify how bits in a bitfield definition should be packed (i.e., where they should go) -- it's totally up to the compiler. You may find how they are laid out to be a certain way in practice given a few compiler samples, but you will be deep into undefined behavior territory.

We are working on this issue in gcc under bug #83784 (and by "we" I mean Andrew Pinski), and I'm hoping that in gcc 10 or 11 we'll have an optimal solution. To be clear, there is a solution now -- it is use a union and define pack and unpack functions to read each bitfield and manually put the data where it belongs in memory. The issue is that when you have properly guessed the bit layout gcc uses then the function should become no-ops and "compile-away". This is currently not happening.

Example:

union a {
    struct {
        int field1:12;
        int field2:20;
    };
    int packed;
};

static union a a_pack(union a a)
{
    union a ret = {0};

    ret.packed = (a.field1 & ((1 << 12) - 1) << 20;
    ret.packed |= a.field2 & ((1 << 20) - 1)

    return ret;
}

static union a a_unpack(union a a)
{
    union a ret = {0};

    ret.field1 = a.packed >> 20;
    ret.field2 = a.packed & ((1 << 20) - 1);

    return ret;
}

Once you do this, you can "pack" your bitfield, read a.packed from Go and then either bit fiddle it or use one of the bitfield implementations.

I told you you wouldn't like the answer. :)



来源:https://stackoverflow.com/questions/56459197/how-to-access-c-bitfield-in-go

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!