我有一个像这样的结构:

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

现在,我要通过cgo访问foo-但找不到任何文档。

天真v := ms.foo提示has no field or method

最佳答案

好吧,你不会喜欢这个答案,但是

  • 没有可移植的方法来执行此操作,因为在C和C++中,位域打包都是“实现定义的”,而
  • Go中的
  • 位域支持似乎很糟糕(可能是由于#1)。

  • 首先,在每个现有的C和C++标准中,位域的布局都是实现定义的。这意味着没有一个标准指定应如何打包位字段定义中的位(即它们应该去哪里)-这完全取决于编译器。在给出一些编译器样本的情况下,您可能会发现它们在实际中的布局方式,但是您将深入研究未定义的行为领域。
    我们正在bug #83784下的gcc中解决此问题(“我是指安德鲁·平斯基”,我希望在gcc 10或11中将有一个最佳解决方案。要明确的是,现在有一个解决方案-它使用联合并定义打包和解压缩函数来读取每个位字段,然后手动将数据放入内存中的位置。问题是,当您正确地猜测gcc使用的位布局时,该功能应变为无操作且“可编译”。这目前没有发生。
    例子:
    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;
    }
    
    完成此操作后,您可以“打包”位域,从Go中读取a.packed,然后对它进行修饰或使用one of the bitfield implementations
    我告诉过你您不想要答案。 :)

    关于go - 如何在Go中访问C位字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56459197/

    10-12 05:13