Go/CGo-如何使用作为指针传递的C数组

Go/CGo-如何使用作为指针传递的C数组,go,cgo,Go,Cgo,我将此作为一个问题/答案发布,因为我花了一段时间来解决,我不介意对我的解决方案进行一些反馈。在Go/CGo中,如何处理作为指针传递的C数组 例如,使用此C结构: struct _GNetSnmpVarBind { guint32 *oid; /* name of the variable */ gsize oid_len; /* length of the name */ ... and ot

我将此作为一个问题/答案发布,因为我花了一段时间来解决,我不介意对我的解决方案进行一些反馈。在Go/CGo中,如何处理作为指针传递的C数组

例如,使用此C结构:

struct _GNetSnmpVarBind {                     
    guint32     *oid;       /* name of the variable */
    gsize       oid_len;    /* length of the name */
    ... and other fields
};  

我想将oid字段转换为Go字符串,如何使用guint32*指针?

我这样做的方式是找到要读取的字节数(guint32*oid的大小),然后对字节数执行binary.read(),然后按大小块循环be字节。回顾起来容易;最困难的部分是得到类型转换,因为Go比C更严格

例如,以下是用于将guint32*转换为Go字符串(表示SNMP OID)的Go代码:

func gIntArrayOidString(oid*\u Ctype\u guint32,oid\u len\u Ctype\u gsize)(结果字符串){
大小:=int(不安全的.Sizeof(*oid))
长度:=int(oid_len)
GB字节:=C.G字节(不安全的.指针(oid),(Ctype_int)(大小*长度))
buf:=字节数。新缓存(GB)
对于i:=0;i1{
返回结果[1:///带前导点
}
返回“”
}
评论



上下文:代码来自。

我假设gsnmp中的值不一定是小端,而是本机字节顺序。我只会使用unsafe.Sizeof遍历数组。e、 g

主程序包
进口(
“不安全”
“fmt”
)
var ints=[…]int32{1,2,3}
func main(){
变量结果字符串
var p*int32=&ints[0]
对于i:=0;i
您可以使用

未经测试,但希望您能理解!不要让切片比C数据活得长,因为它直接指向它

上次我使用它时,我看了一下反汇编,它生成了非常高效的代码

func gIntArrayOidString(oid *_Ctype_guint32, oid_len _Ctype_gsize) (result string) {
    var oids []uint32
    sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&oids)))
    sliceHeader.Cap = oid_len
    sliceHeader.Len = oid_len
    sliceHeader.Data = uintptr(unsafe.Pointer(oid))

    var result string
    for _, value := range oids {
        result += fmt.Sprintf(".%d", value)
    }
    return result[1:]
}

谢谢Axw,我去看看。这正是我要找的!截至2015年,这已从go wiki中删除,因为“它无法安全或可移植地使用”。
func gIntArrayOidString(oid *_Ctype_guint32, oid_len _Ctype_gsize) (result string) {
    var oids []uint32
    sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&oids)))
    sliceHeader.Cap = oid_len
    sliceHeader.Len = oid_len
    sliceHeader.Data = uintptr(unsafe.Pointer(oid))

    var result string
    for _, value := range oids {
        result += fmt.Sprintf(".%d", value)
    }
    return result[1:]
}