正如您所注意到的,问题出在以下代码中:
func (ctxt *Context) StreamsGet(i uintptr) *Stream { streams := (**Stream)(unsafe.Pointer(ctxt.streams)); // I think this is where it's going wrong, I'm brand new to this stuff return (*Stream)(unsafe.Pointer(uintptr(unsafe.Pointer(streams)) + i*unsafe.Sizeof(*streams)));}在代码中,变量
streams是双指针,因此将offset添加到的结果
streams也是双指针(即类型为
**Stream)。但是,在您的摘录中,它被强制转换
*Stream为不正确的。正确的代码是:
func (ctxt *Context) StreamsGet(i uintptr) *Stream { streams := (**Stream)(unsafe.Pointer(ctxt.streams)) // Add offset i then cast it to **Stream ptrPtr := (**Stream)(unsafe.Pointer(uintptr(unsafe.Pointer(streams)) + i*unsafe.Sizeof(*streams))) return *ptrPtr}补充说明:
如果要避免在
Goside 进行指针运算,则可以定义一个_辅助_函数,用于访问C端的指针元素(即流),如下所示:
import "C"import ( "unsafe")type Context C.struct_AVFormatContexttype Stream C.struct_AVStreamfunc (ctx *Context) StreamAt(i int) *Stream { p := (*unsafe.Pointer)(unsafe.Pointer(ctx.streams)) ret := C.ptr_at(p, C.int(i)) return (*Stream)(ret)}func (ctx *Context) StreamAt2(i int) *Stream { ret := C.stream_at((*C.struct_AVFormatContext)(ctx), C.int(i)) return (*Stream)(ret)}您可以选择
ptr_at接受通用(任何)双指针作为其参数的函数,也可以选择
stream_at仅接受指向其的指针作为其参数的更具体的函数
AVFormatContext。:前者的方法可以从任何双指针如用于接入元件
AVProgram**,
AVChapter **等等。后一种方法是优选的,如果我们需要实现额外的处理,如边界检查。



