cgo: Passing a slice/array pointer between Go/C

3724 views
Skip to first unread message

Justin Israel

unread,
Dec 29, 2013, 10:22:11 PM12/29/13
to golan...@googlegroups.com
I know this similar question has been asked before, and it received various suggestions, but I felt I needed to ask it again in a specific way for my problem, along with getting input on the better way to really solve it.

My goal is to move looping code from the Go side into the C side to avoid (and at least test) the overhead of multiple cgo calls per loop. I had a few different ideas of the way to communicate between the two functions.
The data is the float pixels values for an image, packed into an array like R,G,B,R,G,B,...

Go function:
        func GetImageFloatRGB() []float32 

1. malloc, populate, and return a float* from C to Go. Then either copy it into a []float32 and free, or set it on a slice header
        float* getImageFloatRGB()

2. malloc on the Go side and pass in the float*, then do either of the previously mentioned steps
        getImageFloatRGB(float *results)

3. make() a []float32 on the Go side, and pass the backing array pointer into the C call to let it populate
        getImageFloatRGB(float *results)

I haven't really had much luck with any of them yet, as no matter what I try I end up with an all zero array as the result. Although #3, if possible, seems really cool since theoretically I wouldn't have to do anything after the cgo call, as the slice would already be populated.

Both sides of the call have full knowledge of the length of the slice/array.

Most likely I am just getting the casting wrong somewhere, but I would love to first focus on the best suggested approach for passing the data, and then actually figure out the correct way to *do* it. I could show some of my attempts after someone offers the advice on which one would be best.




Justin Israel

unread,
Dec 30, 2013, 7:19:50 AM12/30/13
to golang-nuts
Ah, finally after enough struggling about, I've resolved this. Allocating a slice and then passing over the backing array pointer to C seems to work just fine. 
And the other problem I had mentioned, regarding the results, was also resolved after I discovered that I'm an idiot and didn't initialize a counter in the C code. Thank you Go for having zero values.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Konstantin Khomoutov

unread,
Dec 30, 2013, 8:36:42 AM12/30/13
to Justin Israel, golang-nuts
On Tue, 31 Dec 2013 01:19:50 +1300
Justin Israel <justin...@gmail.com> wrote:

> Ah, finally after enough struggling about, I've resolved this.
> Allocating a slice and then passing over the backing array pointer to
> C seems to work just fine.
> And the other problem I had mentioned, regarding the results, was also
> resolved after I discovered that I'm an idiot and didn't initialize a
> counter in the C code. Thank you Go for having zero values.

Some bits of Go runtime code in the syscall package use the

unsafe.Pointer(&s[0])

"trick" to get the pointer to the first element of the slice 's'.

Justin Israel

unread,
Dec 30, 2013, 4:57:21 PM12/30/13
to Konstantin Khomoutov, golang-nuts
Ya thats pretty neat. I had first started with all this much more complicated stuff with allocating the actual array on either side and then trying to build the slice header  and/or copying the array into a new slice. This ended up super easy to just create my slice at the right size and fill it up.
Reply all
Reply to author
Forward
0 new messages