0

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?

Updates:

Working playground url: https://play.golang.org/p/vpLddEyY8kI

3
  • Your ai value is allocated in Go. You have to allocate C memory using cgo exactly like you would in C. Commented Sep 10, 2020 at 13:10
  • @JimB I tried everything possible, I'd appreciate if you could share a code snippet. Regards. Commented Sep 10, 2020 at 13:11
  • @GaneshRathinavel, use C.malloc to allocate the memory for C.struct_FileInfo. Commented Sep 10, 2020 at 13:12

1 Answer 1

2

The problem

  • arr is a slice of pointers (*C.struct_FileInfo).
  • &arr[0] takes the address of (a pointer to) the first element of that slice.
  • The 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.

Possible solution

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.