问题描述

我正在使用FFmpeg为Windows平台编写一个应用程序,它是golang包装器goav,但是我在理解如何使用C指针获取对它们所指向的数据数组的访问方面遇到困难.

I'm writing an app for the windows platform using FFmpeg and it's golang wrapper goav, but I'm having trouble understanding how to use the C pointers to gain access to the data array they point to.

我正在尝试获取存储在AVFrame类中的数据,并使用Go将其写入文件,最后使用OpenGl中的纹理使视频播放器具有很酷的过渡效果.

I'm trying to get the data stored in the AVFrame class and use Go to write it to a file, and eventually a texture in OpenGl to make a video player with cool transitions.

我认为了解如何转换和访问C数据将使编码变得更加容易.

I think understanding how to cast and access the C data will make coding this a lot easier.

我已经剥离了C代码的所有相关部分,包装程序和我的代码,如下所示:

I've stripped out all the relevant parts of the C code, the wrapper and my code, shown below:

C代码-libavutil/frame.h

C code - libavutil/frame.h

#include <stdint.h>

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    uint8_t *data[AV_NUM_DATA_POINTERS];
}

Golang goav包装器-我真的不知道不安全的情况在这里发生了什么.指针和强制转换,但它使我可以访问基础C代码

Golang goav wrapper - I don't really know whats going on here with the unsafe.Pointers and casting but it gives me access to the underlying C code

package avutil

/*
    #cgo pkg-config: libavutil
    #include <libavutil/frame.h>
    #include <stdlib.h>
*/
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.Pointeruintptr
unsafe.Pointeruintptr

下面是一些示例代码,应在移动操场上按原样运行.

Here's some example code that should run as-is on the go playground.

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)
}

当然,您需要非常确定知道多少个元素,以免访问无效的内存.

Of course, you will need to be very certain you know how many elements there are so that you do not access invalid memory.

这篇关于CGO:如何在Golang中使用指针从C中的数组访问数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!