On Sat, Feb 20, 2021 at 8:34 AM changkun <h...@changkun.de> wrote: > > Dear Ian, thanks for the inspiration and sorry for the late response. I just > got a chance to test your suggestion. > But, it turns out that the wrapping struct can cause the following error: > > panic: runtime error: cgo argument has Go pointer to Go pointer > > If my understanding of Cgo constraints correctly, the panic is to prevent a > potential error when GC moves the Go pointer, > although we don't manipulate the Go pointer (to the channel) from the C side. > > How could we avoid this?
Oh, sorry. There are lots of ways to go, depending on the details. The easiest is to store the channel in a global variable on the Go side, though of course then only one goroutine can use this system at a time. Or you can build a map on the Go side that maps integers to channel, then pass the integer to C which will pass it back to Go and the Go side will look in the map. Ian > On Monday, February 15, 2021 at 9:51:03 PM UTC+1 Ian Lance Taylor wrote: >> >> On Mon, Feb 15, 2021 at 12:39 PM changkun <h...@changkun.de> wrote: >> > >> > Thanks for the hint, but I have some follow-up questions: >> > >> >> >> >> Even if there were a way to do this, an atomic variable is not a good >> >> synchronization mechanism, because the other side has to poll the >> >> variable. >> > >> > Indeed, it the other side will be a spin loop to poll the atomic variable, >> > which ... >> > >> > >> >> >> >> You can do this as a last resort, but it doesn't sound like >> >> you are at a last resort here. I suggest that you have your C >> >> function call a Go function to write a value on a channel. >> > >> > seems easy to write than this (?). >> > >> > Say a Go function foo is called from the C side, to be able to send to the >> > corresponding channel, C must pass that channel to the Go function, which >> > brings to the initial question: pass a channel from Go to C, is it >> > supported at the moment (?) >> > >> > How could a Go function be able to send content to differently allocated >> > channels in correspondingly invoked C functions? >> >> For example, on the Go side write >> >> type chanToUse struct { >> c chan int >> } >> >> //export MyGoFunction >> func MyGoFunction(u unsafe.Pointer, val int) { >> cu = (*chanToUse)(u) >> cu.c <- val >> } >> >> ch := make(chan int) >> ... >> C.MyCFunction(unsafe.Pointer(&chanToUse{ch})) >> >> and on the C side write >> >> void MyCFunction(void *goData) { >> ... >> MyGoFunction(goData, 0); >> } >> >> Yes, it's more work. But it's not a good idea to poll an atomic >> variable in Go. The Go scheduler reacts badly to busy loops. >> >> Ian > > -- > 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+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/19463602-158d-4539-9132-fa6d5b09a8c3n%40googlegroups.com. -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcV69t2%3D03roiheR4oLFRT%2B0cv2ZhScWOK8cGscc01yDHg%40mail.gmail.com.