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.

Reply via email to