Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

website: https://github.com/golang/go/wiki/cgo broken examples #15937

Closed
axet opened this issue Jun 2, 2016 · 8 comments
Closed

website: https://github.com/golang/go/wiki/cgo broken examples #15937

axet opened this issue Jun 2, 2016 · 8 comments

Comments

@axet
Copy link

axet commented Jun 2, 2016

Wiki page contains broken examples in section callback

https://github.com/golang/go/wiki/cgo#function-variables

package main

import (
    "fmt"
    "unsafe"
)

/*
extern void go_callback_int(void* foo, int p1);

// normally you will have to define function or variables
// in another separate C file to avoid the multiple definition
// errors, however, using "static inline" is a nice workaround
// for simple functions like this one.
static inline void CallMyFunction(void* pfoo) {
    go_callback_int(pfoo, 5);
}
*/
import "C"

//export go_callback_int
func go_callback_int(pfoo unsafe.Pointer, p1 C.int) {
    foo := *(*func(C.int))(pfoo)
    foo(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

// we store it in a global variable so that the garbage collector
// doesn't clean up the memory for any temporary variables created.
var MyCallbackFunc = MyCallback

func main() {
    C.CallMyFunction(unsafe.Pointer(&MyCallbackFunc))
}

produces:

axet-laptop:~ axet$ go run test.go 
panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]:
panic(0x40dc800, 0xc82000a2e0)
    /opt/local/lib/go/src/runtime/panic.go:481 +0x3e6
main._cgoCheckPointer0(0x40ba4c0, 0x4182e08, 0xc82000a2d0, 0x1, 0x1, 0x0)
    command-line-arguments/_obj/_cgo_gotypes.go:40 +0x4d
main.main()
    /Users/axet/test.go:36 +0xec
exit status 2
axet-laptop:~ axet$
@OneOfOne
Copy link
Contributor

OneOfOne commented Jun 2, 2016

One rather ugly workaround is to use a map or an array and pass the func index to C, while it's ugly, it's currently the only way I can think of until this (imho regression) is fixed.

/*
extern void go_callback_int(int idx, int p1);
static inline void CallMyFunction(int idx) {
    go_callback_int(idx, 5);
}
*/
import "C"

//export go_callback_int
func go_callback_int(idx C.int, p1 C.int) {
    foo := myCallbacks[idx].(func(C.int))
    foo(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

var myCallbacks = [...]interface{}{
    0: MyCallback,
}

func main() {
    C.CallMyFunction(0)
}

@ianlancetaylor ianlancetaylor changed the title https://github.com/golang/go/wiki/cgo broken examples website: https://github.com/golang/go/wiki/cgo broken examples Jun 2, 2016
@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Jun 2, 2016
@ianlancetaylor ianlancetaylor self-assigned this Jun 2, 2016
@ianlancetaylor
Copy link
Member

This regression is not going to be fixed. See #12416 and https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md .

I'll fix the wiki page.

@ianlancetaylor
Copy link
Member

I've updated the wiki.

@axet
Copy link
Author

axet commented Jun 3, 2016

@inconshreveable can you update an example? This example propose bad hobbits. For example provided solution limit calls of 'register' function by sizeof(int) number.

Golang no longer feels like 'google' it feels like 'int', especially after 1.6 release. You have to consider this guys. And a few more ideas about modules and versioning...

@inconshreveable
Copy link
Contributor

@axet I think you meant to ping @ianlancetaylor

@ianlancetaylor
Copy link
Member

@axet A better place for discussion would be the golang-dev mailing list, not this issue. See https://golang.org/wiki/Questions.

In Go, sizeof(int) is the maximum number of elements you can have in a slice or map. It's not limiting the program. But if you have a better suggestion, I'm happy to adopt it.

@axet
Copy link
Author

axet commented Jun 3, 2016

@ianlancetaylor Ok. This is issue about callback example? Anyway. index incremented evey call, not every element. Which means every sizeof(int) no matter how bit it is and how many elements you have (one for example), it will flip over on next sizeof(int) call. Which can happens in few weeks on high load application. That why I said it is issue and bad hobbits.

I can suggest create wrapper or support it in Go core. If any one would listen...

@ianlancetaylor
Copy link
Member

OK, I added a loop. Thanks.

Can we talk about this on the mailing list now, please?

@golang golang locked and limited conversation to collaborators Jun 3, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants