CGO:如何在Golang中使用指针从C中访问数组中的数据
我正在使用FFmpeg编写一个用于Windows平台的应用程序,它是golang包装器goav,但是我无法理解如何使用C指针来访问他们指向的数据数组。
我正在尝试将数据存储在AVFrame类中,并使用Go将其写入文件,最后使用OpenGl中的纹理来制作具有很酷转换的video播放器。
我认为理解如何投射和访问C数据将使编码变得更加容易。
我已经删除了C代码的所有相关部分,包装器和我的代码,如下所示:
C代码 – libavutil / frame.h
#include typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 uint8_t *data[AV_NUM_DATA_POINTERS]; }
Golang goav包装器 – 我真的不知道这里有什么不安全的.Pointers和cast但它让我可以访问底层的C代码
package avutil /* #cgo pkg-config: libavutil #include #include */ import "C" import ( "unsafe" ) type Frame C.struct_AVFrame func AvFrameAlloc() *Frame { return (*Frame)(unsafe.Pointer(C.av_frame_alloc())) } func Data(f *Frame) *uint8 { return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data)))) }
我的Golang代码
package main import "github.com/giorgisio/goav/avutil" func main() { videoFrame := avutil.AvFrameAlloc() data := avutil.Data(videoFrame) fmt.Println(data) // here i want the values from data[0] to data[7], but how? }
由于库作者没有构造切片头以供您使用,因此您需要将返回值转换为unsafe.Pointer
,然后转换为uintptr
这将允许您对其执行指针运算以便稍后获取元素在记忆中。
这是一些示例代码,应该在go操场上按原样运行。
package main import ( "fmt" "unsafe" ) func main() { nums := []uint8{1, 2, 3, 4, 5, 6, 7, 8} val := &nums[0] // val is the equivalent of the *uint8 the Data function returns ptr := unsafe.Pointer(val) sixthVal := (*uint8)(unsafe.Pointer(uintptr(ptr) + 5*unsafe.Sizeof(*val))) fmt.Println("Sixth element:", *sixthVal) }
当然,您需要非常确定您知道有多少元素,以便您不会访问无效的内存。