cgo:如何将结构体数组从C传递到Go中

huangapple go评论79阅读模式
英文:

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 &lt;&lt; 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&lt;&lt;30 is going to be large enough. That array is immediately converted to a slice, with the length and capacity properly set.

huangapple
  • 本文由 发表于 2015年3月8日 17:57:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/28925179.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定