On Thu, Mar 9, 2017 at 7:00 AM, Miki Tebeka <miki.teb...@gmail.com> wrote:
> Hi There,
>
> (Originally posted on StackOverflow, trying my luck here as well).
>
> I'm trying to extend the code in Calling Go Functions from Other Languages.
> I'd like see how a function returning an error can be handled. See the code
> below, I get "panic: runtime error: invalid memory address or nil pointer
> dereference" when running the Python code. Any ideas on how to fix this?
>
> gmath.go
>
> package main
>
>
> import (
>     "fmt"
> )
>
>
> import "C"
>
>
> //export Div
> func Div(x, y float64) (float64, error) {
>     fmt.Printf("Div called: x=%f, y=%f\n", x, y)
>     if y == 0 {
>         return 0, fmt.Errorf("ZeroDivisionError")
>     }
>     return x / y, nil
> }
>
>
> func main() {}
>
>
> gmath.py
>
> import ctypes
>
>
>
>
> class GoInterface(ctypes.Structure):
>     _fields_ = [
>         ('t', ctypes.c_void_p),
>         ('v', ctypes.c_void_p),
>     ]
>
>
>
>
> class DivRet(ctypes.Structure):
>     _fields_ = [
>         ('result', ctypes.c_float),
>         ('error', GoInterface),
>     ]
>
>
>
>
> lib = ctypes.cdll.LoadLibrary('./gmath.so')
> lib.Div.argtypes = [ctypes.c_double, ctypes.c_double]
> lib.Div.restype = DivRet
>
>
> r = lib.Div(1.2, 2.3)
>
> Example run
>
> $ make
> go build -o gmath.so -buildmode=c-shared gmath.go
> $ python gmath.py
> Div called: x=1.200000, y=2.300000
> panic: runtime error: invalid memory address or nil pointer dereference
> [signal SIGSEGV: segmentation violation code=0x1 addr=0x17
> pc=0x7fbe5fda928d]
>
>
> goroutine 17 [running, locked to thread]:
> main._cgoexpwrap_448ea9090bef_Div.func1(0xc42003cea8)
>     command-line-arguments/_obj/_cgo_gotypes.go:46 +0x42
> main._cgoexpwrap_448ea9090bef_Div(0x3ff3333333333333, 0x4002666666666666,
> 0x3fe0b21642c8590b, 0x0, 0x0)
>
>
>     command-line-arguments/_obj/_cgo_gotypes.go:48 +0xaa
> [1]    29009 abort (core dumped)  python gmath.py
>
> I've tried calling the Go code directly from C - with same results.

I don't know if this is your problem, but a Go float64 corresponds to
a C double, not a C float.

You might get more information if you set GOTRACEBACK=system in the
environment when running the program.

In general you can not return an error from an exported function,
because an error is an interface value, and in general an interface
contains a Go pointer, and an exported Go function is not permitted to
return a Go pointer
(https://golang.org/cmd/cgo/#hdr-Passing_pointers).  Your specific
program may work because the Go pointer may point to a constant string
that is statically allocated rather than in heap memory.  I'm not
sure.  You  might try running your program with GODEBUG=cgocheck=2 to
see if that picks anything up.

You can't expect Python to do anything useful with a Go error value,
so this seems like an odd thing to try to get working.

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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to