3 回答
TA贡献1770条经验 获得超3个赞
Sonia已经回答了她自己的问题,我只想提供为什么需要两次类型转换的原因。
从unsafe.Pointer的文档中:
1)任何类型的指针值都可以转换为Pointer。
2)指针可以转换为任何类型的指针值。
3)可以将uintptr转换为Pointer。
4)指针可以转换为uintptr。
由于var ptr uint64
不是指针(如类型uint64
不是指针),ptr
不能直接转换为unsafe.Pointer
使用规则1。因此,有必要首先转换ptr
到uintptr
,然后从uintptr
向Pointer
下面的规则3。
TA贡献1828条经验 获得超4个赞
cgo将联合公开为一个字节数组,其大小足以容纳联合的最大成员。在您的情况下是64位,而这8个字节,[8]byte。如您所展示的,此数组的内容保存并集的内容,使用它与指针转换有关。
但是,您可以使用阵列的地址来大大简化该过程。对于一个C._GNetSnmpVarBind命名的data,
guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))
当我第一次看到它时,我并没有完全理解这一点,但是当我将其分解时,它变得更加清晰:
var data C._GNetSnmpVarBind // The C struct
var union [8]byte = data.value // The union, as eight contiguous bytes of memory
// The first magic. The address of the first element in that contiguous memory
// is the address of that memory. In other words, the address of that union.
var addr *byte = &union[0]
// The second magic. Instead of pointing to bytes of memory, we can point
// to some useful type, T, by changing the type of the pointer to *T using
// unsafe.Pointer. In this case we want to interpret the union as member
// `guint32 *ui32v`. That is, T = (*C.guint32) and *T = (**C.guint32).
var cast **C.guint32 = (**C.guint32)(unsafe.Pointer(addr))
// The final step. We wanted the contents of the union, not the address
// of the union. Dereference it!
var guint32_star *C.guint32 = *cast
归功于Alan Shen的文章,该文章以对我最终有意义的方式描述了工会的cgo表示形式。
- 3 回答
- 0 关注
- 340 浏览
添加回答
举报