c将带有 uint8_t *num 的 C 结构转换为 Go



C 结构:

typedef struct info_s {
int len;
uint8_t *num;
}info_t;
extern int info_collect(int unit, info_t *info,
data_t *data);

去包装器:

type Info struct {
Len     int
num     []uint8
}
//Method to convert C.info_t => Info
func (inf C.info_s) Info() Info {
var tInf Info
tInf.Len = int(inf.len)
for i := 0; i < int(tInf.Len); i++ {
tInf.num[i] = uint8(inf.num[i])
}
return Info{
Len: int(inf.len),
Info: (*C.uchar)(unsafe.Pointer(&info.num[0])),
}
}

如何从 go 包装器访问uint8_t *num? 我认为定义的方法不正确。 num - (num []uint8( 的结构是访问它的正确方法吗?

添加缺失的拼图。C 中也有一个 API 将 C 结构作为输入。

现在,当我调用此 API 时,我会出现运行时恐慌:

data := []uint8{1, 2, 3}
var inf = new(C.info_t)
inf.len = 64
inf.num = data
C.info_collect(C.int(unit), (*C.info_t)(unsafe.Pointer(&info)),
(*C.data_t)(unsafe.Pointer(&data)))
Panic: runtime error: cgo argument has Go pointer to Go pointer

在 Go 中,num只是长度为len(num)[]uint8类型(或其别名[]byte(的切片。要将数据从 C 类型info_t复制到 Go 托管内存类型[]uint8,请编写一个 Gonum函数:

package main
import (
"fmt"
"unsafe"
)
/*
#include <stdint.h>
typedef struct info_s {
int len;
uint8_t *num;
} info_t;
*/
import "C"
func num(info C.info_t) []uint8 {
n := make([]uint8, 0, info.len)
for i := _Ctype_int(0); i < info.len; i++ {
u8 := *(*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(info.num)) + uintptr(i)))
n = append(n, u8)
}
return n
}
func main() {
test := []uint8{1, 2, 3}
fmt.Println(len(test), test)
info := C.info_t{
len: _Ctype_int(len(test)),
num: (*_Ctype_uint8_t)(&test[0]),
}
infonum := (*[1 << 20]uint8)(unsafe.Pointer(info.num))[:info.len]
fmt.Println(info.len, infonum)
n := num(info)
fmt.Println(len(n), n)
}

输出:

3 [1 2 3]
3 [1 2 3]
3 [1 2 3]

最新更新