2

I am trying to understand cgo. I can call C functions from go and the other way also. I tried doing something different and it didn't work.

go code:

// main.go

package main

/*
extern void myfunction(GoSlice s);
*/
import "C"

func main() {
    var s [5]byte
    C.myfunction(s[:])
}

C code:

// main.c

#include "_cgo_export.h"

#include <stdint.h>

void myfunction(GoSlice s)
{
    for (int i = 0; i < s.len; i++)
        printf("%hhu ", ((uint8_t *)s.data)[i]);
}

The compilation fails because GoSlice is not defined at the time of the C function declaration in main.go. Also, I can't include _cgo_export.h in main.go to get the definition. Is there any way I can get this working ? Note that I can get the functionality working using C compatible data types. But I want to directly use go data type here.

Rahul
  • 963
  • 9
  • 14
  • 1
    Possible duplicate of [How to pass pointer to slice to C function](http://stackoverflow.com/questions/42530538/how-to-pass-pointer-to-slice-to-c-function) – eugenioy May 17 '17 at 02:29
  • Why do you want to pass a slice header to C? Even if it were allowed, there's really no reason. Pass in the data, or a pointer to the data. – JimB May 17 '17 at 02:43
  • Actually, this is part of the problem I was trying to solve. Following is a simplified description of my requirement. I want to create a slice in go and pass it to C code. The C code would call back into a go function multiple times by passing the slice as first argument and a string as second argument. The second go function would append the string to the slice. When the control returns back to the first go function, it would have a list of strings in the slice. So, the slice has to travel go -> C -> go and back. – Rahul May 17 '17 at 04:43
  • 1
    @Rahul: You can't pass a slice to a C function without disabling the cgo safety checks, so just start with the correct types to do it in C to avoid the risk of losing the referenced memory to the garbage collector. – JimB May 17 '17 at 13:03
  • @JimB: I have my code working by passing unsafe.Pointer(&myslice) to my C function accepting "void *" and from C function to the go function. I just wanted to avoid passing "void *" pointers around and wanted to rely on the compiler to check argument types for me. Since that does not seem to be possible, I'll stick to the "void *" for now. – Rahul May 18 '17 at 05:02
  • @eugenioy: in the question you refer to, the OP wants to modify a go datastructure in C. I don't want to do that in my program. I just want to pass it to the C function so that it can be passed to a go callback. I put this extra piece of information in my comment above. Sorry if my original question was incomplete. – Rahul May 18 '17 at 05:08

0 Answers0