3 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個贊
Sonia已經(jīng)回答了她自己的問題,我只想提供為什么需要兩次類型轉(zhuǎn)換的原因。
從unsafe.Pointer的文檔中:
1)任何類型的指針值都可以轉(zhuǎn)換為Pointer。
2)指針可以轉(zhuǎn)換為任何類型的指針值。
3)可以將uintptr轉(zhuǎn)換為Pointer。
4)指針可以轉(zhuǎn)換為uintptr。
由于var ptr uint64
不是指針(如類型uint64
不是指針),ptr
不能直接轉(zhuǎn)換為unsafe.Pointer
使用規(guī)則1。因此,有必要首先轉(zhuǎn)換ptr
到uintptr
,然后從uintptr
向Pointer
下面的規(guī)則3。

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超4個贊
cgo將聯(lián)合公開為一個字節(jié)數(shù)組,其大小足以容納聯(lián)合的最大成員。在您的情況下是64位,而這8個字節(jié),[8]byte。如您所展示的,此數(shù)組的內(nèi)容保存并集的內(nèi)容,使用它與指針轉(zhuǎn)換有關(guān)。
但是,您可以使用陣列的地址來大大簡化該過程。對于一個C._GNetSnmpVarBind命名的data,
guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))
當(dāng)我第一次看到它時,我并沒有完全理解這一點(diǎn),但是當(dāng)我將其分解時,它變得更加清晰:
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 關(guān)注
- 382 瀏覽
添加回答
舉報