go呼び出しc全面解析

1785 ワード

一、goのポインタ
pointer type、uintptr、unsafe.Pointer
  • pointer type:ポインタタイプで、*intが整数ポインタタイプ
  • と呼ばれるような具体的なベースタイプポインタの名前があります.
  • uintptr:アドレスを格納するための符号なし整数.ただ1つのアドレスで、アドレスのデータに対していかなるタイプの解釈をしていないで、演算をすることができて、例えば:var p uintptr p+=1.uintが見ると
  • unsafe.Pointer:unsafeパッケージの1つで、任意のポインタタイプを指すポインタタイプで、Cのvoid*に相当します.他の4種類の特殊な操作があります.
  • 任意のタイプのポインタはunsafeに変換できる.Pointer
  • unsafe.Pointerは任意の種類のポインタ
  • に変換することができる.
  • unsafe.Pointerはuintptr
  • に移行可能
  • uintpはunsafeに移行することができる.Pointer

  • したがって、ポインタタイプとuintptr変換はunsafeを通過する.Pointer、すべてのgoのポインタの操作はCよりずっと面倒です.
  • 例1[]byteの2つの要素をuint 16の値に変換するには、encoding/binaryパッケージのbinaryを使用することができる.LittleEndian.UIT 16関数変換、ここではポインタの変換
  • を説明するためだけである
        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
    ", 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
    ", p) //p:0xc000071f5c p++ pb = unsafe.Pointer(p) u16 = *((*uint16)(pb)) fmt.Printf("u16:%#04x
    ", u16) //u16:0x0302

    二、goに直接Cコードを埋め込む
    三、go windowsのdllを呼び出す
    四、goはlinuxのsoを呼び出す
    五、goコードをdllとsoにコンパイルする