简体   繁体   English

难以访问 go 中的嵌套 C 联合成员

[英]Difficulty accessing nested C union member in go

Disclaimer: I am new to Go/CGo.免责声明:我是 Go/CGo 的新手。

I'm working with this C struct on a 64 bit platform, trying to access the uint32 member of a union我正在 64 位平台上使用这个 C 结构,试图访问联合的 uint32 成员

typedef enum {
    n = 0,
    ix = 1,
    iy = 3 
} enum_x;

struct smallStruct_s {
     union {
        uint32 a[4];
        uint32 b[8];
        uint32 c[16];
    } u;
} smallStruct_t;

struct bigStruct_s {
   enum_x fa;
   union {
        uint32 member_to_access; <<<<<< This is member that needs to be accessed
        smallStruct_t an;
   } un_t;
} bigStruct_t;

I am facing difficulty accessing/mutating member_to_access in Go given I have access to bigStruct_t which can be accessed using C.bigStruct_t .鉴于我可以访问bigStruct_t可以使用C.bigStruct_t访问,我在 Go 中访问/ member_to_access时遇到困难。

How can I pass the address of member_to_access using unsafe.Pointer to a function which accepts void* in C without violating any memory constraints.如何使用unsafe.Pointer将 member_to_access 的地址传递给 function ,它在 C 中接受 void* 而不会违反任何 ZCD69B4957F06CD818D7BF3D61980E291 约束。

The machine is little endian机器是小端

I tried using byteArray and C buffers as mentioned in Golang CGo: converting union field to Go type but couldn't understand why the function takes size of 8 bytes array as parameter.我尝试使用 Golang CGo 中提到的 byteArray 和 C 缓冲区:将联合字段转换为 Go 类型,但不明白为什么 ZC1C425268E68385D1AB5074C17A94F14 的参数大小为字节数组。

Union can be represented as array of bytes, so this field weighs as size of largest element ([sizeof_union's_largest_element]byte).联合可以表示为字节数组,因此该字段的权重为最大元素的大小([sizeof_union's_largest_element]byte)。 Enum can be represented as int.枚举可以表示为 int。

I propose to use offsets for that:我建议为此使用偏移量:

type bigStruct struct {
    instance unsafe.Pointer
}

func (bs *bigStruct) fa() int {
    return int(*(*C.int)(bs.instance))
}

func (bs *bigStruct) memberToAccess() uint32 {
    // C.sizeof_int refers to sizeof(enum_x)
    return uint32(*(*C.uint32_t)(unsafe.Pointer(uintptr(bs.instance) + C.sizeof_int)))
}

func (bs *bigStruct) an() *C.smallStruct_t {
    return (*C.smallStruct_t)(unsafe.Pointer(uintptr(bs.instance) + C.sizeof_int))
}

func (bs *bigStruct) an_u() []byte {
    // cgo having same thought about and takes smallStruct_t.u as array
    return (*C.smallStruct_t)(unsafe.Pointer(uintptr(bs.instance) + C.sizeof_int)).u[:]
}

func (bs *bigStruct) next_field_after_un_t() *Type {
    return (*Type)(unsafe.Pointer(uintptr(bs.instance) + C.sizeof_int + C.sizeof_smallStruct_t))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM