Reputation: 3
I get this error:
Ticker ticked
unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x105c4152e]
goroutine 17 [running, locked to thread]:
runtime.throw(0x105c74358, 0x5)
/usr/local/go/src/runtime/panic.go:616 +0x81 fp=0xc420050d48 sp=0xc420050d28 pc=0x105bd6951
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:395 +0x211 fp=0xc420050d98 sp=0xc420050d48 pc=0x105beabf1
main.callme(0x105baefc0)
/Users/xxx/go/src/test2/test2.go:29 +0xce fp=0xc420050e90 sp=0xc420050d98 pc=0x105c4152e
main._cgoexpwrap_f53316e445a2_callme(0x105baefc0)
_cgo_gotypes.go:45 +0x2b fp=0xc420050ea8 sp=0xc420050e90 pc=0x105c4144b
runtime.call32(0x0, 0x7ffeea2482b0, 0x7ffeea248348, 0x8)
/usr/local/go/src/runtime/asm_amd64.s:573 +0x3b fp=0xc420050ed8 sp=0xc420050ea8 pc=0x105bfe7eb
runtime.cgocallbackg1(0x0)
/usr/local/go/src/runtime/cgocall.go:316 +0x19c fp=0xc420050f58 sp=0xc420050ed8 pc=0x105bb284c
runtime.cgocallbackg(0x0)
/usr/local/go/src/runtime/cgocall.go:194 +0xda fp=0xc420050fc0 sp=0xc420050f58 pc=0x105bb261a
runtime.cgocallback_gofunc(0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:826 +0x9b fp=0xc420050fe0 sp=0xc420050fc0 pc=0x105bffdbb
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420050fe8 sp=0xc420050fe0 pc=0x105c00a31
The go code is :
package main
import "time"
import "fmt"
import "C"
type convert func()
//export callme
func callme(fn convert) {
doneChan := make(chan bool)
go func() {
time.Sleep(time.Second * 5)
doneChan <- true
}()
ticker := time.NewTicker(time.Millisecond * 500)
for {
select {
case <- ticker.C:
fmt.Println("Ticker ticked")
fn()
case <- doneChan:
fmt.Println("Done")
return
}
}
}
func main() {
ticker := time.NewTicker(time.Millisecond * 1000)
time.Sleep(time.Millisecond * 1500)
ticker.Stop()
fmt.Println("Ticker stopped")
}
The python code is:
from ctypes import *
def print_tick():
print("hey")
return 0
lib = cdll.LoadLibrary("./test2.so")
CMPFUNC = CFUNCTYPE(c_int)
cmp_func = CMPFUNC(print_tick)
callme = lib.callme
callme(cmp_func)
This was just a test code to see how can I use callback between python and go and if that is possible. Ideally, The python side would start the go code to run in the background. go engine is receiving a stream of messages and upon receiving a message, the go engine would call the callback function from python and pass those messages to python.
Upvotes: 0
Views: 1082
Reputation: 426
The problem here is the type of the argument to "callme". The python code uses ctypes to give it a C style function pointer. Your Go code receives it as a Go function, which it is not.
First, "callme" needs to be defined like this:
func callme(fn C.convert)
Then C.convert needs to be defined. Go documentation https://golang.org/cmd/cgo/ describes how you can add a piece of C code to a Go source file.
/*
typedef void (*convert) ();
*/
import "C"
Since it is not possible to call a function pointer directly, you need to create a C function that takes the pointer as a parameter, and calls it.
/*
typedef void (*convert) ();
static inline void call_c_func(convert ptr) {
(ptr)();
}
*/
import "C"
Now C.call_c_func can be used to call the callback function received from python, replacing a direct call to fn().
//fn()
C.call_c_func(fn)
Upvotes: 3
Reputation: 4595
This will not work without using C as an intermediary from go back into python.
A go function pointer will not look the same as a python function pointer. The go code crashes when it expects to see fn as a go function. But that is a python function pointer. The boldface debacle message is funny - they have clearly anticipated this error and use 0xb01dfacedebac1e as the pointer value.
You might try simply using a return value of callme in python. When a message comes in, return it from callme, and then from python call callme again for the next message. The return value in python needs to be something python can understand.
Otherwise, if it is possible to call from c into python, then you might choose to use a c function as an intermediary, and supply that c function as the callback.
Upvotes: 0