2022-06-18:golang与 C++数据结构类型对应关系是怎样的?
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)
}
公众号:福大大架构师每日一题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
2021-06-18 2021-06-18:已知数组arr,生成一个数组out,out的每个元素必须大于等于1,当arr[cur]>arr[cur-1]时,out[cur]>out[cur-1];当arr[cur]>arr