go - 重新打包 C 类型导致 Go 中出现类型转换错误

标签 go casting package cgo

我正在尝试重新打包一些与现有 C 库集成的 go 代码。

以下完美运行。

文件 1:

package avcodec

type Codec C.struct_AVCodec

文件 2:

package avformat

//#cgo pkg-config: libavformat libavcodec
//#include <libavformat/avformat.h>
//#include <libavcodec/avcodec.h>
import "C" 
import (    
"unsafe" 
) 

type Codec C.struct_AVCodec

func (s *FormatContext) AvFormatGetVideoCodec() *Codec {    
  result := C.av_format_get_video_codec((*C.struct_AVFormatContext)(s))
  return (*Codec)(result) // <- This works. Codec is defined in this package.
}

如果我尝试将编解码器从文件 2 引用或移动到单独的包(例如,文件 1),我会收到错误消息:

无法将 (func literal)((*C.struct_AVFormatContext)(s)) (类型 *C.struct_AVCodec)转换为类型 *Codec

例如,这失败了:

package avformat

//#cgo pkg-config: libavformat libavcodec
//#include <libavformat/avformat.h>
//#include <libavcodec/avcodec.h>
import "C" 
import (    
"avcodec"
"unsafe" 
) 

func (s *FormatContext) AvFormatGetVideoCodec() *avcodec.Codec {    
 result := C.av_format_get_video_codec((*C.struct_AVFormatContext)(s))      
 return (*avcodec.Codec)(result) // <- This fails. Codec defined in avcodec.
}

这也失败了:

package avformat

//#cgo pkg-config: libavformat libavcodec
//#include <libavformat/avformat.h>
//#include <libavcodec/avcodec.h>    
import "C" 
import ( 
"avcodec"   
"unsafe" 
) 

type Codec avcodec.Codec

func (s *FormatContext) AvFormatGetVideoCodec() *Codec {    
  result := C.av_format_get_video_codec((*C.struct_AVFormatContext)(s))
  return (*Codec)(result) // <- This also fails. Codec is based on avcodec.Codec.
}

我愿意:

  1. 理解失败的原因,并且
  2. 确定如何更改包装,以便该函数使用 avcodec 包中定义的 Codec 类型。

提前致谢。

最佳答案

由于 Go 表示类型的方式而失败。

例如,给定:

//Ex1
package avformat 
//.. deleted for simplicity

type Codec C.struct_AVCodec

...和

//Ex2
package avcode 
//.. deleted for simplicity

type Codec C.struct_AVCodec

在上面的代码中,ex1 中的 C.struct_AVCodec 与 ex2 中的 C.struct_AVCodec 不同,尽管它们在词法上是相同的。

具体来说,ex1中的完全限定类型是avformat._Ctype_struct_AVCodec,而ex2是avcodec._Ctype_struct_AVCodec

这解释了为什么 package avformat 中的函数试图将任何内容从外部类型(在本例中是从 package avcodec)转换为本地 C.struct_AVCodec 失败了。

解决方案

为了让它发挥作用,我依赖于类型断言。

package avformat

func (s *FormatContext) AvformatNewStream(c avcodec.ICodec) *Stream {
  v, _ := c.(*C.struct_AVCodec)
  return (*Stream)(C.avformat_new_stream((*C.struct_AVFormatContext)(s), (*C.struct_AVCodec)(v)))
}

...和

package avcodec

type ICodec interface{}

关于go - 重新打包 C 类型导致 Go 中出现类型转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43192754/

相关文章:

regex - 如何提取子字符串

c++ - 连接 C 风格的强制转换操作毫无意义吗?

sql - PostGIS 按 ST_Distance 排序 - 不按距离排序记录

exception - 找到数据时PL SQL引发异常

javascript - 无法从github安装yarn包

linux - 从具有多个二进制文件的源文件创建 debian 包

go - 如何使用 Go Gin 高效调用 localhost Handler?以及如何获取正在运行的url?

go - http.Server — 获取 URL 片段

go - 使用 Golang 减少访问 Bigtable 的时间

c - 为什么我得到 "arithmetic of pointer type is required"?