使用reflect确定结构字段是否为不完整的Cgo类型



我有一些通用代码,它使用反射来处理结构字段。这些字段可能包括也可能不包括通过Cgo引用的C类型。

我遇到的一个问题是,上述C类型可能是"C";不完全结构";,例如:CCD_ 1。这可能会导致代码稍后出现死机。

理想情况下,我需要能够检查和跳过这样的实例,而不会意外跳过有效字段。

我考虑过检查Type.Size()返回的值是否为0,但空的Go结构将返回相同的值。

有办法做到这一点吗?

TL;DR总结:Cgo没有不完整的类型,所以这里没有什么可测试的;但是,您不应该以导致运行时死机的方式使用不完整的类型。(展示一个最小的可重复的例子,有人可能会告诉你哪里出了问题。(


在C中,不能有不完整类型的对象,但可以有一个指向(某个不完整类型(的指针类型的值,您可以将其存储在指向不完全类型的指针类型的对象中。无法跟随(取消引用(指针。

奇怪的是,Cgo似乎允许跟随指针。这可能是因为Go中没有不完整类型,所以Cgo只是将C对象变成一个不包含字段且大小为零的结构:

package main
// #include <stdlib.h>
//
// struct incomp;
// struct incomp *foo() {
//     return malloc(10);
// }
import "C"
import (
"fmt"
"reflect"
)
func newFoo() *C.struct_incomp {
return C.foo()
}
func main() {
p := newFoo()
t := reflect.TypeOf(*p)
if t.Kind() != reflect.Struct {
panic("not a struct")
}
fmt.Println("Size:", t.Size())
fmt.Println("NumFields:", t.NumField())
}

我有一些使用反射来处理结构字段的泛型代码。这些字段可能包括也可能不包括通过Cgo…引用的C类型。。。这可能会导致代码稍后出现死机。

考虑到以上情况(不完整的"对象"本身的大小为零(,永远不要将实际的不完整类型Cgo类型嵌入到Go类型中。始终使用(C(指针。否则,Go类型中的任何后续字段都将覆盖C代码中的实际字段。

最新更新