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

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

將 Go []byte 轉(zhuǎn)換為 C *char

將 Go []byte 轉(zhuǎn)換為 C *char

Go
溫溫醬 2021-12-20 10:14:20
我有一個 byte.Buffer,我使用 binary.Write() 函數(shù)將數(shù)據(jù)打包。然后我需要將此字節(jié)數(shù)組發(fā)送到 C 函數(shù)。使用 Go 1.6 我沒有成功解決這個問題。buf := new(bytes.Buffer) //create my buffer....binary.Write(buf, binary.LittleEndian, data) //write my data to buffer hereaddr := (*C.uchar)(unsafe.Pointer(&buf.Bytes()[0])) //convert buffers byte array to a C arrayrc := C.the_function(addr, C.int(buf.Len())) //Fails here它在調(diào)用 C 函數(shù)時(shí)失敗,說:panic: runtime error: cgo argument has Go pointer to Go pointerC函數(shù):int the_function(const void *data, int nbytes);我能夠使以下內(nèi)容工作,但將字節(jié)數(shù)組轉(zhuǎn)換為字符串感覺不對。有一個更好的方法嗎?這種方法是否有對數(shù)據(jù)產(chǎn)生副作用的風(fēng)險(xiǎn)?addr := unsafe.Pointer(C.CString(string(buf.Bytes()[0]))同樣,這需要在引入更嚴(yán)格的 cgo 指針規(guī)則的 Go 1.6 下工作。謝謝你。
查看完整描述

2 回答

?
30秒到達(dá)戰(zhàn)場

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個贊

如果要使用第一種方法,則需要在函數(shù)調(diào)用參數(shù)之外創(chuàng)建切片,并避免臨時(shí)分配的切片頭或參數(shù)中的外部結(jié)構(gòu),因此cgo檢查不會將其視為存儲在 Go 中的指針.


b := buf.Bytes()

rc := C.the_function(unsafe.Pointer(&b[0]), C.int(buf.Len()))

該C.CString方法將更安全,因?yàn)閿?shù)據(jù)被復(fù)制到 C 緩沖區(qū)中,因此沒有指向 Go 內(nèi)存的指針,并且后面的切片bytes.Buffer不會被修改或超出范圍。您需要轉(zhuǎn)換整個字符串,而不僅僅是第一個字節(jié)。這種方法確實(shí)需要分配和復(fù)制兩次,但是如果數(shù)據(jù)量很小,與 cgo 調(diào)用本身的開銷相比,這可能不是問題。


str := buf.String()

p := unsafe.Pointer(C.CString(str))

defer C.free(p)

rc = C.the_function(p, C.int(len(str)))

如果該解決方案中不能接受數(shù)據(jù)的 2 個副本,則還有第三種選擇,您可以自己分配 C 緩沖區(qū),并將單個副本復(fù)制到該緩沖區(qū)中:


p := C.malloc(C.size_t(len(b)))

defer C.free(p)


// copy the data into the buffer, by converting it to a Go array

cBuf := (*[1 << 30]byte)(p)

copy(cBuf[:], b)

rc = C.the_function(p, C.int(buf.Len()))

但是對于后兩種選擇,不要忘記釋放 malloc 的指針。


查看完整回答
反對 回復(fù) 2021-12-20
?
qq_遁去的一_1

TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個贊

您的程序崩潰是因?yàn)樵?go1.6 中將指針傳遞給 C 的規(guī)則發(fā)生了變化(有關(guān)詳細(xì)信息,請參閱https://tip.golang.org/doc/go1.6#cgo)。

我不知道你的程序?yàn)槭裁磿罎?,所以我?chuàng)建了 Go issue https://github.com/golang/go/issues/14546。

但是不管這個問題的答案如何,我都不會使用內(nèi)部位bytes.Buffer(就像你一樣)直接傳遞給 cgo。該bytes.Buffer實(shí)現(xiàn)可以改變未來,你程序?qū)悠粕衩?。我只是將您需要的?shù)據(jù)復(fù)制到任何合適的結(jié)構(gòu)中,然后使用它傳遞給 cgo。


查看完整回答
反對 回復(fù) 2021-12-20
  • 2 回答
  • 0 關(guān)注
  • 449 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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