// go run cgo.go
package main
/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
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))
}
// go build -o cgo_test cgo.go
package main
/*
#include <stdlib.h>
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..")
}