go呼び出しc全面解析
1785 ワード
一、goのポインタ
pointer type、uintptr、unsafe.Pointer pointer type:ポインタタイプで、 と呼ばれるような具体的なベースタイプポインタの名前があります. uintptr:アドレスを格納するための符号なし整数.ただ1つのアドレスで、アドレスのデータに対していかなるタイプの解釈をしていないで、演算をすることができて、例えば: 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関数変換、ここではポインタの変換 を説明するためだけである例2 uintptrの演算によりデータ に取り出す.
二、goに直接Cコードを埋め込む
三、go windowsのdllを呼び出す
四、goはlinuxのsoを呼び出す
五、goコードをdllとsoにコンパイルする
pointer type、uintptr、unsafe.Pointer
*int
が整数ポインタタイプvar p uintptr p+=1
.uintが見るとしたがって、ポインタタイプとuintptr変換はunsafeを通過する.Pointer、すべてのgoのポインタの操作はCよりずっと面倒です.
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
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にコンパイルする