美文网首页
go调用c全面解析

go调用c全面解析

作者: 水上清风 | 来源:发表于2018-10-17 23:37 被阅读17次

    一、go的指针

    pointer type、 uintptr和unsafe.Pointer

    • pointer type: 指针类型,有具体基础类型指针的名称,如 *int叫整型指针类型

    • uintptr: 一个无符号整数,用于存放地址。只是一个地址,没有对地址处的数据做任何类型解释,可以做运算,如:var p uintptr p+=1。当uint看即可

    • unsafe.Pointer: unsafe包中的一个类型,指向任意指针类型的指针类型,相当于C中void*。它有四钟其他类型的特殊操作:

      • 任意类型指针能转化为unsafe.Pointer
      • unsafe.Pointer能够转化为任意类型的指针
      • unsafe.Pointer可转为uintptr
      • uintp可以转为unsafe.Pointer

      因此,一个指针类型和uintptr转化要通过unsafe.Pointer,所有go中指针操作比C麻烦太多。

    • 示例1 将[]byte中两个元素转为uint16值,可以使用 encoding/binary包中的binary.LittleEndian.Uint16函数转化,这里只是为了说明指针的转化

        b := []byte{0x01, 0x02, 0x3, 0x4}
        var u16 uint16
    
        pb := unsafe.Pointer(&b[1]) //pb指向b第二个元素的地址,注:&b不是slice的第一元素的地址,要用&b[0],如果为数组 [4]byte{}则&b为第一个元素的地址,原因参与雨痕的go学习笔记。
        u16 = *((*uint16)(pb))      //将b的2,3元素转为一个uint16的数,小端模式0x0302,大端模式0x0203; intel和amd CPU都是小段模式
        fmt.Printf("u16:%#04x\n", u16) //0x0302
    
    • 示例2 通过uintptr的运算取到数据
        var u16 uint16
        var p uintptr
        b := [4]byte{0x01, 0x02, 0x3, 0x4}
        //uintptr和指针类型不能直接转换
        //p = uintptr(&b)           //cannot convert &b (type *[4]byte) to type uintptr
        //u16 = *((*uint16)(p + 2)) //cannot convert p + 2 (type uintptr) to type *uint16
        pb := unsafe.Pointer(&b)
        p = uintptr(pb)
        fmt.Printf("p:%p\n", p) //p:0xc000071f5c
        p++
        pb = unsafe.Pointer(p)
        u16 = *((*uint16)(pb))
        fmt.Printf("u16:%#04x\n", u16) //u16:0x0302
    
    

    二、go中直接嵌入C代码

    三、go调用windows的dll

    四、go调用linux的so

    五、go代码编译为dll和so

    相关文章

      网友评论

          本文标题:go调用c全面解析

          本文链接:https://www.haomeiwen.com/subject/xsbdzftx.html