基本类型
Go 字符串和切片
参考 reflect
包 StringHeader
和 SliceHeader
定义
_GoString_
预定义类型
结构体、联合和枚举类型
结构体在 C 中使用 struct <name>
来指定类型,但是在 Go 中包定义的情况下就需要使用 C.struct_<name>
来指定对应的结构体类型,或者使用 typedef
指定别名后使用。
结构体字段与 Go 关键字重名
比如 type
关键字,在 C 结构体中的 type
字段可以在 Go 中用 _type
来代替:
/*
struct A {
int type;
}
import "C"
func main() {
var a C.struct_A
print(C._type)
*/
联合体在 Go 中使用 C.union_<name>
来访问,并且会被转换成对应大小的字节数组。
联合体在 Go 中的操作方式
联合体在 Go 的操作方式有三种:
- 在 C 语言中定义辅助函数
- 通过
encoding/binary
手工解码成员(注意端序问题) - 通过
unsafe
包强制转换为对应类型(性能最好)- 对于嵌套联合体的访问复杂,建议使用 C 辅助函数处理
枚举类型使用 C.enum_<name>
来访问
数组、字符串和切片
C | Go | |
---|---|---|
数组 | 指向特定类型特定长度 的一段内存的指针 | 值类型,长度也是其一部分 |
字符串 | char 类型的数组,长度由表示结尾的 NULL 字符的确定 |
一段长度确定的只读 byte 类型的内存,结构参考 reflect.StringHeader |
切片 | 无 | 简化版动态数组,结构参考 reflect.SliceHeader |
CGO 的 C 虚拟包中提供了一组函数用于双向转换:
// string
func C.CString(string) *C.char
func C.GoString(*C.char) string
func C.GoStringN(*C.char, C.int) string // 长度为 n 的数组
// bytes
// 通过 malloc 分配,需要手动 free
func C.CBytes([]byte) unsafe.Pointer
C.GoBytes(unsafe.Pointer, C.int) []byte
指针的转换
通过 unsafe.Pointer
可以实现不同类型指针的互相转换。
Go 禁止数值类型到指针类型的转换,但是可以通过 uintptr
类型来实现