第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang CGo:將聯(lián)合字段轉(zhuǎn)換為Go類型

Golang CGo:將聯(lián)合字段轉(zhuǎn)換為Go類型

Go
白板的微信 2021-05-13 17:19:33
我正在64位平臺上使用此C結(jié)構(gòu),嘗試訪問值聯(lián)合中的ui32v字段:struct _GNetSnmpVarBind {  guint32       *oid;       /* name of the variable */  gsize     oid_len;    /* length of the name */  GNetSnmpVarBindType   type;       /* variable type / exception */  union {    gint32   i32;           /* 32 bit signed   */    guint32  ui32;          /* 32 bit unsigned */    gint64   i64;           /* 64 bit signed   */    guint64  ui64;          /* 64 bit unsigned */    guint8  *ui8v;          /*  8 bit unsigned vector */    guint32 *ui32v;         /* 32 bit unsigned vector */  }         value;      /* value of the variable */  gsize     value_len;  /* length of a vector in bytes */};我可以為每個并集元素編寫一個C包裝函數(shù),但是出于教學(xué)目的,我寧愿在Go中工作。這是我嘗試訪問ui32v字段的方式:func union_to_guint32_ptr(cbytes [8]byte) (result *_Ctype_guint32) {  buf := bytes.NewBuffer(cbytes[:])  var ptr uint64  if err := binary.Read(buf, binary.LittleEndian, &ptr); err == nil {    return (*_Ctype_guint32)(unsafe.Pointer(ptr))  }  return nil}但是這給出了一個錯誤,無法將ptr(uint64類型)轉(zhuǎn)換為unsafe類型。那么,如何做我轉(zhuǎn)換一個UINT64將轉(zhuǎn)至類型指向一個C guint32?我已經(jīng)嘗試了多種轉(zhuǎn)換,分別轉(zhuǎn)換為uintptr,然后轉(zhuǎn)換為* _Ctype_guint32,轉(zhuǎn)換為uintptr,然后使用unsafe.Pointer,...我的理由是:我傳遞了8個字節(jié)的數(shù)組。將其轉(zhuǎn)換為uint64,即內(nèi)存地址。將其轉(zhuǎn)換為指向guint32的指針(即guint32的C數(shù)組),并作為結(jié)果返回-聯(lián)合字段“ value”為guint32 *。
查看完整描述

3 回答

?
德瑪西亞99

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)換ptruintptr,然后從uintptrPointer下面的規(guī)則3。


查看完整回答
反對 回復(fù) 2021-05-31
?
明月笑刀無情

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表示形式。


查看完整回答
反對 回復(fù) 2021-05-31
  • 3 回答
  • 0 關(guān)注
  • 382 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號