package main
import "C"
import (
"fmt"
"unsafe"
)
func main() {
len := 10
str := C.xmalloc(C.int(len))
defer C.free(unsafe.Pointer(str.s))
gostr := C.GoStringN(str.s, str.len)
fmt.Printf("retlen=%vn", str.len)
println(gostr)
}
结果:
retlen=10 0123456789
你可以将整个golang的结构体指针转换成c语言的结构体指针,前提是golang 的结构体和c 的结构体定义是一一对应的(后面有介绍怎么穿件一一对应的结构体),但是c语言的结构体指针无法直接转换成golang语言的结构体指针:
package main
import (
"fmt"
"unsafe"
)
// struct x {
// int y, z;
// };
//
// int sum(struct x a) {
// return a.y + a.z;
// }
//
import "C"
type X struct{ Y, Z int32 }
func main() {
a := &X{5, 7}
fmt.Println(a, "->", C.sum(*((*C.struct_x)(unsafe.Pointer(a)))))
}
cgo -godefs 是专门用来将c语言结构体转换成golang语言对应的结构体的工具。
package main
import "C"
import (
"fmt"
"unsafe"
)
type Foo struct{ a, b int32 }
func main() {
foo := Foo{10, 20}
foos := []*Foo{&Foo{1, 2}, &Foo{3, 4}}
fmt.Println("from C land")
C.pass_struct((*C.Foo)(unsafe.Pointer(&foo)))
C.pass_array((**C.Foo)(unsafe.Pointer(&foos[0])), C.int(len(foos)))
fmt.Println("a & b should have incremented with 1")
fmt.Println("from Go land")
for _, foo := range foos {
fmt.Printf("%d : %dn", foo.a, foo.b)
}
}
Output:
from C land 10 : 20 1 : 2 3 : 4 a & b should have incremented with 1 from Go land 2 : 3 4 : 52、Go -> C 整形指针
package main
import "C"
import (
"fmt"
"unsafe"
)
func main() {
rlen := C.int(0)
len := 10
cstr := C.xmalloc(C.int(len), &rlen)
defer C.free(unsafe.Pointer(cstr))
gostr := C.GoStringN(cstr, rlen)
fmt.Printf("retlen=%vn", rlen)
println(gostr)
}
xmalloc函数的第二个参数是int*,这里设计为一个输入、输出参数。我们在Golang中使用C.int类型的指针就可以;
其返回值是一个char*,在Golang中就是 *C.char,由于返回值是指针,其内存由malloc分配,因此需要在Golang中对其内存进行释放。



