CGO中遇到的一些问题及解决办法记录
文章目录
- 在CGO开发中可能遇到的问题
- 结构体的使用可能会出现以下问题:
- 未能正确解析结构体
- 在不同包中定义同一C语言结构体会导致编译错误信息不一致
CGO中遇到的一些问题
1. struct 结构体
1.1 结构体没有正确解析
reference : https://stackoverflow.com/questions/59353668/get-the-struct-from-c-to-golang
报错信息形如
cannot use engine.GoToCKey(startKey) (type engine._Ctype_struct___2) as type _Ctype_struct___0 in assignment
问题分析:
当遇到一个结构体被解析为如 type _Ctype_struct___0 这样的非标准形式时,则表明该结构体并未被 CGO 正确识别为标准类型表(CTypes)。这一现象通常由以下因素引起:
主要原因是,在定义一个自定义数据类型时选择了关键字 typedef 作为类型别名,并未在其类型的体内预先指定名字(即未附加类型名称),从而导致编译器无法正确识别其对应的标准类型表信息。
例如如下所示:
typedef struct {
int field1;
float field2;
} struct1;
指上文提到的一个定义,在C语言环境中是可以正常应用的。当采用CGO时可能会遇到问题:该编译器无法识别该结构体类型,在程序运行过程中会导致错误。
解决方法
定义struct时,总是在首部指出struct的名字
typedef struct struct1 {
int field1;
float field2;
} struct1;
1.2 同一个C结构体在不同的package下使用,报错类型不一致
报错信息形如
cannot use ss (type _Ctype_struct_DBKey) as type engine._Ctype_struct_DBKey in argument to engine.GoToCKey
原因分析
https://golang.org/cmd/cgo/#hdr-Go_references_to_C
Cgo converts C types into corresponding unexposed Go types. Given that these conversions remain internal, it is imperative for a Go package to refrain from exposing underlying C types via its API. Specifically, a particular C type employed within one Go package differs from the same type utilized in another.
当CGO将一个C语言类型的实例转化为Go语言对象时,在这种情况下会被转换为非导出形式。这等同于说其对应的签名会受到所在包的修饰影响。尽管从C语言的角度看它们属于同一类别实例,在不同Go包环境中引用相同的_C_type对象时会被视为不同的实体,并且会产生相应的错误信息如前述示例所示。
解决方法目前尚未发现理想的解决方案, 但倾向于将相关逻辑整合至同一包内, 对于外部调用C类型函数的情况, 建议在同一包中复制
