亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

轉到 / Cgo - 如何訪問 C 結構的字段?

轉到 / Cgo - 如何訪問 C 結構的字段?

Go
慕蓋茨4494581 2022-09-19 20:54:29
我在Go中開發了一個應用程序,用于將音頻文件從一種格式轉碼為另一種格式:我使用使用 Cgo 綁定 FFmpeg C 庫的 goav 庫:https://github.com/giorgisio/goav/戈夫圖書館; 具有一個類型定義,該定義將原始 FFmpeg 庫 C-結構 AV輸出格式轉換為:package avformattype (    OutputFormat               C.struct_AVOutputFormat)在我的代碼中,我有一個名為 的變量,該變量的類型是.outputFOutputFormatC.struct_AVOutputFormat真正的結構有以下字段:CAVOutputFormatname, long_name, mime_type, extensions, audio_codec, video_codec, subtitle_codec,..以及許多領域。請參見: https://ffmpeg.org/doxygen/2.6/structAVOutputFormat.html我通過以下方式驗證了情況并到達:fmt.Println(outputF){0x7ffff7f23383 0x7ffff7f23907 0x7ffff7f13c33 0x7ffff7f23383 86017 61 0 128 <nil> 0x7ffff7f8cfa0 <nil> 3344 0x7ffff7e3ec10 0x7ffff7e3f410 0x7ffff7e3ecc0 <nil> 0x7ffff7e3dfc0 <nil> <nil> <nil> <nil> <nil> <nil> 0 0x7ffff7e3e070 0x7ffff7e3e020 <nil>}音頻編解碼器字段位于位置,包含586017我使用包驗證了字段名稱:reflectval := reflect.Indirect(reflect.ValueOf(outputF))fmt.Println(val)fmt.Println("Fieldname: ", val.Type().Field(4).Name)Output:Fieldname:  audio_codec我嘗試使用以下命令訪問原始字段:audio_codecAVOutputFormatfmt.Println(outputF.audio_codec)ERROR: outputF.audio_codec undefined (cannot refer to unexported field or method audio_codec)fmt.Println(outputF._audio_codec)ERROR: outputF._audio_codec undefined (type *avformat.OutputFormat has no field or method _audio_codec)正如我在Cgo文檔中讀到的:在Go文件中,可以通過在下劃線前綴來訪問作為Go中關鍵字的C結構字段名稱:如果x指向帶有名為“type”的字段的C結構,x._type訪問該字段。無法在 Go 結構中表示的 C 結構字段(如位字段或未對齊的數據)在 Go 結構中被省略,替換為適當的填充以到達下一個字段或結構的末尾。但我不知道我做錯了什么。編輯:好吧,肯定不需要下劃線,因為audio_codec不是Go中的關鍵字。我現在明白了。但是仍然存在一個問題,為什么我無法訪問CStruct字段“audio_codec”。
查看完整描述

1 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

GO / CGO有一些特質,你在這里碰到:

type OutputFormat C.struct_AVOutputFormat是 go 類型聲明,而不是別名。將其視為薄包裝而不是別名可能會有所幫助。因此,C.struct_AVOutputFormat字段不會導出,這就是您獲得OutputFormat != C.struct_AVOutputFormatERROR: outputF.audio_codec undefined (cannot refer to unexported field or method audio_codec)

如果該字段被調用Audio_codec它將符合go對導出標識符的定義,我們可以訪問它,但事實并非如此。

有一種方法可以解決這個問題,但我建議在繼續之前三思而后行,因為它使用不安全的指針,并且您的程序可能會在運行時失去可移植性和/或穩定性。如果您想了解更多信息,這是不安全指針的良好介紹

現在,如果您確實確定要執行此操作,解決方案是將指針轉換為不安全的指針,然后將其轉換為指向 的指針。請注意,這需要您加載 FFMPEG 標頭才能獲得OutputFormatC.struct_AVOutputFormatC.struct_AVOutputFormat

//#cgo pkg-config: libavformat

//#include <libavformat/avformat.h>

import "C"

import (

    "fmt"

    "unsafe"

    "github.com/giorgisio/goav/avformat"

)


func getOutput() *avformat.OutputFormat {

  // calls out to avformat and gets an OutputFormat back

}


func main() {

    outputF := getOutput()

    coutput := *(*C.struct_AVOutputFormat)(unsafe.Pointer(outputF))


    fmt.Println(coutput.audio_codec) // This should now work

}

警告:我還沒有測試cgo包配置和導入是否正確,但這適用于一個簡單的C庫,我站起來嘗試一下。<libavformat/avformat.h>


查看完整回答
反對 回復 2022-09-19
  • 1 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號