[英]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.