cgo example

  • go access c struct
  // go run cgo.go
  package main

/*
#include 
#include 
#include 
#include 
typedef struct student {
        int age;
        char *name;
}student;

void student_init(void **ptr,char *name,int age) {
        size_t len = strlen(name);
        student *st = (student *)calloc(1,sizeof(student));
        assert(st!=NULL);
        st->age = age;
        st->name = (char *)calloc(1,len+1);
        memcpy(st->name,name,len);
        *ptr = st;
        fprintf(stdout,"...call student_init...\n");
}
student *student_new(char *name,int age) {
        size_t len = strlen(name);
        student *st = (student *)calloc(1,sizeof(student));
        assert(st!=NULL);
        st->age = age;
        st->name = (char *)calloc(1,len+1);
        memcpy(st->name,name,len);

        fprintf(stdout,"...call student_new...\n");
        return st;
}
void student_destroy(void *ptr) {
        student *st = (student *)ptr;
        if(st !=NULL)
        {
                free(st->name);
                free(st);
                st=NULL;
                fprintf(stdout,"...call student_destroy...\n");
        }
}
void student_print(void  *ptr) {
        student *st = (student *)ptr;
        fprintf(stdout,"student addr=%p,name=%p,age=%p\n",st,st->name,&st->age);
        fprintf(stdout," student {name=%s,age=%d}\n",st->name,st->age);
}
*/
import "C"
import (
        "fmt"
        "unsafe"
)

func main() {
        var st1 unsafe.Pointer
        name := C.CString("perrynzhou")
        C.student_init(&st1, name, 30)
        C.student_print(st1)
        C.student_destroy(st1)
        C.free(unsafe.Pointer(name))

        var st2 *C.student
        name2 := C.CString("hello")
        st2 = C.student_new(name2, 100)
        fmt.Printf("init student st2 {age:%d,name:%s}\n", st2.age, C.GoString(st2.name))
        C.student_print(unsafe.Pointer(st2))

        C.free(unsafe.Pointer(st2.name))
        name3 := C.CString("join")
        st2.name = name3
        st2.age = 67
        fmt.Printf("after change student st2 {age:%d,name:%s}\n", st2.age, C.GoString(st2.name))
        C.student_print(unsafe.Pointer(st2))
        C.student_destroy(unsafe.Pointer(st2))

}
image.png
  • go access c memory
//    go build  -o cgo_test cgo.go 

package main

/*

#include 

void *alloc() {
        static int count = 0;
        void *d = malloc(sizeof(int));
        *((int *)d) = count++;
        return d;
}
*/
import "C"
import (
        "fmt"
        "runtime"
        "sync"
        "time"
        "unsafe"
)

type CStruct struct {
        sync.Mutex
        name     string
        allocCnt int
        memory   unsafe.Pointer
}

func (cs *CStruct) alloc(name string, id int) {
        cs.name = fmt.Sprintf("CStruct-%s-%d", name, id)
        cs.Lock()
        defer cs.Unlock()
        cs.allocCnt++
        fmt.Printf("%s begin with alloc,count=%d\n", cs.name, cs.allocCnt)
        cs.memory = C.alloc()
        runtime.SetFinalizer(cs, free)
}
func free(cs *CStruct) {
        C.free(unsafe.Pointer(cs.memory))
        cs.Lock()
        defer cs.Unlock()
        cs.allocCnt--
        fmt.Printf("%s end with free count=%d\n", cs.name, cs.allocCnt)
}
func CStructTest(i int) {
        var c1, c2 CStruct
        c1.alloc("c1", i)
        c2.alloc("c2", i)
}
func main() {
        for i := 0; i < 10; i++ {
                CStructTest(i)
                time.Sleep(time.Second)
        }
        runtime.GC()
        time.Sleep(time.Second)
        fmt.Println("done..")
}
image.png

你可能感兴趣的:(cgo example)