在使用 container/list 过程中用其保存C指针,但是发现通过Element ->Value 获取元素值并不能直接转换为unsafe.Pointer使用,只能祭出reflect 大法。通过reflect -> ValueOf -> Pointer 搞定,以下是示例:
package main
// go build -gcflags=all="-N -l" clist.go
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
struct Dog {
int id;
char name[16];
};
*/
import "C"
import (
"log"
"fmt"
"reflect"
"unsafe"
"container/list"
)
func main() {
l := list.New()
var ptr *C.struct_Dog
for i := 1; i < 5; i ++ {
dog := C.malloc(C.sizeof_struct_Dog)
if dog == nil {
log.Print("malloc error")
return
}
ptr = (*C.struct_Dog)(unsafe.Pointer(dog))
ptr.id = C.int(i)
fmt.Println("Add Dog", dog)
l.PushBack(unsafe.Pointer(dog))
}
log.Print("Init list done.");
for e := l.Front(); e != nil; e = e.Next() {
v := e.Value
ptr = (*C.struct_Dog)(unsafe.Pointer(reflect.ValueOf(v).Pointer()))
fmt.Println("Dog", unsafe.Pointer(ptr), "id ", ptr.id)
c.free(unsafe.Pointer(ptr))
}
}
输出
Add Dog 0x8367e0
Add Dog 0x836800
Add Dog 0x836820
Add Dog 0x836840
2018/12/15 17:37:35 Init list done.
Dog 0x8367e0 id 1
Dog 0x836800 id 2
Dog 0x836820 id 3
Dog 0x836840 id 4