Reputation: 1335
I am trying to create a struct, in Go, where one of it's children is an array of struct and then translate it to C using CGO.
I tried something like this in Go
*/
typedef struct FileInfo{
int64_t Size;
char *Name;
}FileInfo;
typedef struct Result{
FileInfo **files;
}Result;
int64_t GetResult(void **presult, FileInfo **files) {
Result *result = (Result *)malloc(sizeof(Result));
result->files=files;
*presult = result;
int64_t ptr = (int64_t)result;
return ptr;
}
*/
import "C"
func Run() {
var arr []*C.struct_FileInfo
ai := C.struct_FileInfo{
Size: C.int64_t(1234),
Name: C.CString("some name"),
}
arr = append(arr, &ai)
var presult unsafe.Pointer
ptr := C.GetResult(&presult, &arr[0])
println("\nResult struct pointer: %v", ptr)
}
It threw an panic: runtime error: cgo argument has Go pointer to Go pointer
error.
How to I fix this error?
Working playground url: https://play.golang.org/p/vpLddEyY8kI
Upvotes: 0
Views: 512
Reputation: 55443
arr
is a slice of pointers (*C.struct_FileInfo
).&arr[0]
takes the address of (a pointer to) the first element of that slice.ai
variable, the address of which becomes the first element of arr
, is allocated by Go.Hence:
arr[0]
contains &ai
, which is a pointer to C.struct_FileInfo
allocated by Go.arr
is also managed by Go and hence &arr[0]
is "a Go pointer to Go pointer".Please read this thoroughly.
One solution is to call C.malloc
to allocate enough bytes to store a C.struct_FileInfo
. This way, you will have Go pointer (&arr[0]) to C pointer, which is fine.
Don't forget to C.free
it after you're done with that memory.
Upvotes: 2