调用Go语言从Python时出现”invalid memory address”错误。

huangapple go评论81阅读模式
英文:

"invalid memory address" when calling Go from Python

问题

我正在尝试扩展从其他语言调用Go函数中的代码。我想看看如何处理返回错误的函数。运行Python代码时,我得到panic: runtime error: invalid memory address or nil pointer dereference的错误。有什么解决方法吗?

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)

示例运行

$ 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'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

<!-- language: lang-golang -->

package main

import (
	&quot;fmt&quot;
)

import &quot;C&quot;

//export Div
func Div(x, y float64) (float64, error) {
	fmt.Printf(&quot;Div called: x=%f, y=%f\n&quot;, x, y)
	if y == 0 {
		return 0, fmt.Errorf(&quot;ZeroDivisionError&quot;)
	}
	return x / y, nil
}

func main() {}

gmath.py

<!-- language: lang-py -->

import ctypes


class GoInterface(ctypes.Structure):
    _fields_ = [
        (&#39;t&#39;, ctypes.c_void_p),
        (&#39;v&#39;, ctypes.c_void_p),
    ]


class DivRet(ctypes.Structure):
    _fields_ = [
        (&#39;result&#39;, ctypes.c_float),
        (&#39;error&#39;, GoInterface),
    ]


lib = ctypes.cdll.LoadLibrary(&#39;./gmath.so&#39;)
lib.Div.argtypes = [ctypes.c_double, ctypes.c_double]
lib.Div.restype = DivRet

r = lib.Div(1.2, 2.3)

Example run

<!-- language: lang-none -->

$ 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

答案1

得分: 2

似乎问题的关键在于结果的错误部分。如果我将错误更改为字符串并返回(float64,*C.char),它就可以工作。

英文:

It appears that the error part of result is the initial issue. If I change error to a string and return the (float64, *C.char), it works.

huangapple
  • 本文由 发表于 2017年3月9日 15:25:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/42689133.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定