【发布时间】:2021-04-10 05:11:15
【问题描述】:
我有一个新手 CGO 问题,我想知道是否有人可以帮助我。当 GODEBUG 设置为 cgocheck=2 运行时,我的应用程序崩溃并显示以下内容
write of Go pointer 0xc0003b72c0 to non-Go memory 0x7fefa0016810
fatal error: Go pointer stored into non-Go memory
导致问题的代码是
cArray := C.malloc(C.size_t(len(fd.Faces)) * C.size_t(unsafe.Sizeof(uintptr(0))))
defer C.free(unsafe.Pointer(cArray))
a := (*[1<<30 - 1]*C.struct_Box)(cArray)
for index, value := range fd.GetFaceRectangles() {
box := &C.struct_Box{
left: C.int(value.Min.X),
top: C.int(value.Min.Y),
right: C.int(value.Max.X),
bottom: C.int(value.Max.Y),
}
a[index] = box
}
cBoxCount := C.int(len(fd.Faces))
ret := C.facerec_compute_multi(rec.ptr, cImgData, cLen, &a[0], cBoxCount)
特别是这一行:
a[index] = box
我了解数组的内存是在 C 中使用 malloc 分配的。我正在尝试将 C Box 添加到数组中,然后再将其传递给 C 函数。解决这个问题的方法是让我在 C 中编写一个函数,该函数可以接收数组和创建结构所需的项目,而我在 C 中执行该部分吗?我试图最小化对 C 的调用次数,所以如果我可以从 Go 创建数组,那就太好了。真的很苦恼如何安全地将一组数据传递给 C 中的函数。
【问题讨论】:
-
不确定我是否可以制定答案,因为这对我来说很难测试,但这是我的想法:1) 尝试将
box转换为unsafe.Pointer甚至uintptr在将其分配给a[index]之前。 2) 您也许还可以在 Go 中构建整个数组,然后将其转换为uintptr并将其传递给 C。 -
如果你还没有读过这篇文章:go101.org/article/unsafe.html