英文:
cgo: How to pass struct array from c to go
问题
C部分:
struct Person {...}
struct Person * get_team(int * n)
Go部分:
n := C.int(0)
var team *C.struct_Person = C.get_team(&n)
defer C.free(unsafe.Pointer(team))
我可以通过这种方式获取数组的第一个元素。但是如何获取包含n个元素的整个数组呢?以及如何安全地释放它们?
英文:
The C part:
struct Person {...}
struct Person * get_team(int * n)
The Go part:
n := C.int(0)
var team *C.struct_Person = C.get_team(&n)
defer C.free(unsafe.Pointer(team))
I can get the first element of the array in this way. But how to get the whole array with n elements?
and how to free them safely?
答案1
得分: 15
首先,即使你在使用Go语言,当你添加cgo时,就不再有所谓的“安全”了。你需要自己确定何时以及如何释放内存,就像你在C语言中编程一样。
在Go语言中,将C数组转换为切片的最简单方法是通过数组进行转换:
team := C.get_team()
defer C.free(unsafe.Pointer(team))
teamSlice := (*[1 << 30]C.struct_Person)(unsafe.Pointer(team))[:teamSize:teamSize]
实际上,并没有分配最大尺寸的数组,但是Go语言要求数组的大小是常量,而1<<30
足够大了。该数组立即被转换为切片,并且长度和容量被正确设置。
英文:
First, even though you’re using Go, when you add cgo there is no longer any "safe". It's up to you to determine when and how you free the memory, just as if you were programming in C.
The easiest way to use a C array in go is to convert it to a slice through an array:
team := C.get_team()
defer C.free(unsafe.Pointer(team))
teamSlice := (*[1 << 30]C.struct_Person)(unsafe.Pointer(team))[:teamSize:teamSize]
The max-sized array isn't actually allocated, but Go requires constant size arrays, and 1<<30
is going to be large enough. That array is immediately converted to a slice, with the length and capacity properly set.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论