2022-06-18:golang与 C 数据结构类型对应关系是怎样的?
答案2022-06-18:
uintptr和unsafe.Pointer相当于c 的void*,也就是任意指针。
uintptr可以参与指针运算,unsafe.Pointer不能参与指针运算。
c 和golang对照表如下:
c 类型 | golang类型 | 备注 |
---|---|---|
char | byte | |
char * | string | 函数入参或出参 |
char * | uintptr或者*byte | 结构体成员或者回调函数参数 ,不能用string |
byte | byte | |
byte * | *byte | |
int16 | int16 | |
int16 * | *int16 | |
uint16 | uint16 | |
uint16 * | *uint16 | |
int32 | int32 | |
int32 * | *int32 | |
uint32 | uint32 | |
uint32 * | *uint32 | |
int64 | int64 | |
int64 * | *int64 | |
uint64 | uint64 | |
uint64 * | *uint64 | |
float | float32 | |
float* | *float32 | |
double | float64 | |
double* | *float64 | |
bool | bool | |
void * | uintptr | |
结构体 | 结构体 | |
结构体* | *结构体 | |
枚举 | int32 | |
typedef 返回类型 (*函数名)(参数列表) | type 函数名=func(参数列表)uintptr | 返回类型占用的内存小于uintptr,需要指定为uintptr |
结构体中的函数指针 | uintptr |
go类型和uintptr的相互转换如下:
go源类型 | go目标类型 | 转换方法 |
---|---|---|
int | uintptr | uintptr(a)。byte,int16,int32,int64都可以 |
uintptr | int | int(a)。byte,int16,int32,int64都可以 |
*int | uintptr | unsafe.Pointer(a)。所有指针都是这种转换方式,函数指针例外 |
uintptr | *int | (*int)(unsafe.Pointer(a))。所有指针都是这种转换方式,函数指针例外 |
float32 | uintptr | unsafe.Pointer(&a)。注意:跟int的不一样 |
uintptr | float32 | *(*float32)(unsafe.Pointer(&a))。注意:跟int的不一样 |
float64 | uintptr | unsafe.Pointer(&a)。注意:跟int的不一样 |
uintptr | float64 | *(*float64)(unsafe.Pointer(&a))。注意:跟int的不一样 |
结构体 | uintptr | unsafe.Pointer(&a) |
uintptr | 结构体 | *(*结构体)(unsafe.Pointer(&a)) |
string | uintptr | 见代码UintPtrFromString |
uintptr | string | 见代码StringFromPtr |
bool | uintptr | 见代码CBool |
uintptr | bool | 见代码GoBool |
func | uintptr | syscall.NewCallback(a)或者syscall.NewCallbackCDecl(a)。这是函数指针 |
uintptr | func | 不知道怎么转换,待定 |
func bytePtrFromString(str string) (res *byte) {
res, _ = syscall.BytePtrFromString(str)
return
}
// string → uintptr
func UintPtrFromString(str string) uintptr {
return uintptr(unsafe.Pointer(bytePtrFromString(str)))
}
// uintptr → string
func StringFromPtr(sptr uintptr) (res string) {
if sptr <= 0 {
return
}
buf := make([]byte, 0)
for i := 0; *(*byte)(unsafe.Pointer(sptr uintptr(i))) != 0; i {
buf = append(buf, *(*byte)(unsafe.Pointer(sptr uintptr(i))))
}
res = string(buf)
return
}
// uintptr → bool
func GoBool(val uintptr) bool {
if val != 0 {
return true
}
return false
}
// bool → uintptr
func CBool(val bool) uintptr {
if val {
return 1
}
return 0
}
// func转uintptr
func NewCallback(fn interface{}) uintptr {
//return syscall.NewCallbackCDecl(fn)
return syscall.NewCallback(fn)
}