英文:
panic: runtime error: cgo result has Go pointer
问题
你好,最近我尝试从Python代码中调用一个打印一些除法结果的Golang函数,该函数使用for循环。以下是recap.go的完整代码:
package main
import (
"C"
"strconv"
)
//export PrintAlg
func PrintAlg(debug bool) string {
var b200 int = 0
var b300 int = 0
var b400 int = 0
var x string = "A"
if debug == true {
// extra
} else if debug == false {
for i := 1; i <= 100; i++ {
if i%4 == 0 && i%3 == 0 {
b200++
b300++
b400++
} else if i%4 == 0 && !(i%3 == 0) {
b400++
b200++
} else if i%2 == 0 && i%3 == 0 && !(i%4 == 0) {
b200++
b300++
} else if i%3 == 0 && !(i%2 == 0) && !(i%4 == 0) {
b300++
} else if i%2 == 0 && !(i%3 == 0) && !(i%4 == 0) {
b200++
} else if i%2 == 0 && i%3 == 0 && i%4 == 0 {
b200++
b300++
b400++
}
}
x = strconv.Itoa(b200) + " " + strconv.Itoa(b300) + " " + strconv.Itoa(b400)
}
return x
}
func main() {
}
然后,我尝试使用CTYPES(在Python代码中)调用PrintAlg函数。当我从命令行运行Python代码时,出现了以下错误:
panic: runtime error: cgo result has Go pointer
goroutine 17 [running, locked to thread]:
panic({0x67322a80, 0xc00004a0a0})
C:/Program Files/Go/src/runtime/panic.go:1147 +0x3a8
runtime.cgoCheckArg(0x67320da0, 0xc00004a090, 0x10, 0x0, {0x6732cc4f, 0x19})
C:/Program Files/Go/src/runtime/cgocall.go:514 +0x4d8
runtime.cgoCheckResult({0x67320da0, 0xc00004a090})
C:/Program Files/Go/src/runtime/cgocall.go:630 +0x54
_cgoexp_ba17693967af_PrintAlg(0x108efee9c0)
_cgo_gotypes.go:39 +0x5a
runtime.cgocallbackg1(0x67315640, 0x0, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:306 +0x29a
runtime.cgocallbackg(0x0, 0x0, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:232 +0x106
runtime.cgocallbackg(0x67315640, 0x108efee9c0, 0x0)
<autogenerated>:1 +0x36
runtime.cgocallback(0x0, 0x0, 0x0)
C:/Program Files/Go/src/runtime/asm_amd64.s:915 +0xd7
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1581 +0x1
你可以如何修复这个错误?
英文:
Hello i was recently trying to call a golang function from python code that is printing some division things with for loop.
Full code of recap.go:
package main
import (
"C"
"strconv"
)
//export PrintAlg
func PrintAlg(debug bool) string {
var b200 int = 0
var b300 int = 0
var b400 int = 0
var x string = "A"
if debug == true {
// extra
} else if debug == false {
for i := 1; i <= 100; i++ {
if i%4 == 0 && i%3 == 0 {
b200++
b300++
b400++
} else if i%4 == 0 && !(i%3 == 0) {
b400++
b200++
} else if i%2 == 0 && i%3 == 0 && !(i%4 == 0) {
b200++
b300++
} else if i%3 == 0 && !(i%2 == 0) && !(i%4 == 0) {
b300++
} else if i%2 == 0 && !(i%3 == 0) && !(i%4 == 0) {
b200++
} else if i%2 == 0 && i%3 == 0 && i%4 == 0 {
b200++
b300++
b400++
}
}
x = strconv.Itoa(b200) + " " + strconv.Itoa(b300) + " " + strconv.Itoa(b400)
}
return x
}
func main() {
}
then i tryed to call PrintAlg function with CTYPES (in python code). Then when i ran the python code from cmd, this error occured:
panic: runtime error: cgo result has Go pointer
goroutine 17 [running, locked to thread]:
panic({0x67322a80, 0xc00004a0a0})
C:/Program Files/Go/src/runtime/panic.go:1147 +0x3a8
runtime.cgoCheckArg(0x67320da0, 0xc00004a090, 0x10, 0x0, {0x6732cc4f, 0x19})
C:/Program Files/Go/src/runtime/cgocall.go:514 +0x4d8
runtime.cgoCheckResult({0x67320da0, 0xc00004a090})
C:/Program Files/Go/src/runtime/cgocall.go:630 +0x54
_cgoexp_ba17693967af_PrintAlg(0x108efee9c0)
_cgo_gotypes.go:39 +0x5a
runtime.cgocallbackg1(0x67315640, 0x0, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:306 +0x29a
runtime.cgocallbackg(0x0, 0x0, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:232 +0x106
runtime.cgocallbackg(0x67315640, 0x108efee9c0, 0x0)
<autogenerated>:1 +0x36
runtime.cgocallback(0x0, 0x0, 0x0)
C:/Program Files/Go/src/runtime/asm_amd64.s:915 +0xd7
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1581 +0x1
what can i do for fixing this error?
答案1
得分: 1
Go运行时对字符串的实现是:
type stringStruct struct {
str unsafe.Pointer
len int
}
当你从Go的PrintAlg
函数中返回时,即return x
,Go会返回一个指向Go字符串x
底层字节的Go内存实例stringStruct
。
panic: runtime error: cgo result has Go pointer
阅读cgo文档,特别是Passing_pointers部分,了解详情。
在Go中,可以这样编写:
func PrintAlg(debug bool) *C.char {
// ...
return C.CString(x)
}
以返回一个指向C字符串实例的指针。在不再需要时释放指针。
$ go build -buildmode=c-shared -o _recap.so
$ python3 recap.py
50 33 25
$
recap.go
:
package main
import (
"C"
"strconv"
)
//export PrintAlg
func PrintAlg(debug bool) *C.char {
var b200 int = 0
var b300 int = 0
var b400 int = 0
var x string = "A"
if debug == true {
// extra
} else if debug == false {
for i := 1; i <= 100; i++ {
if i%4 == 0 && i%3 == 0 {
b200++
b300++
b400++
} else if i%4 == 0 && !(i%3 == 0) {
b400++
b200++
} else if i%2 == 0 && i%3 == 0 && !(i%4 == 0) {
b200++
b300++
} else if i%3 == 0 && !(i%2 == 0) && !(i%4 == 0) {
b300++
} else if i%2 == 0 && !(i%3 == 0) && !(i%4 == 0) {
b200++
} else if i%2 == 0 && i%3 == 0 && i%4 == 0 {
b200++
b300++
b400++
}
}
x = strconv.Itoa(b200) + " " + strconv.Itoa(b300) + " " + strconv.Itoa(b400)
}
return C.CString(x)
}
func main() {}
recap.py
:
import ctypes
recap = ctypes.cdll.LoadLibrary('./_recap.so')
printAlg = recap.PrintAlg
printAlg.argtypes = [ctypes.c_bool]
printAlg.restype = ctypes.c_void_p
free = recap.free
free.argtypes = [ctypes.c_void_p]
px = printAlg(False)
x = ctypes.string_at(px).decode('utf-8')
free(px)
print(x)
英文:
The Go runtime implementation of a string is
type stringStruct struct {
str unsafe.Pointer
len int
}
When you return from your Go PrintAlg
function - return x
- Go returns a Go memory instance of stringStruct
which points to the underlying bytes of the Go string x
.
panic: runtime error: cgo result has Go pointer
Read the cgo documentation, especially Passing_pointers, for details.
In Go, write
func PrintAlg(debug bool) *C.char {
// ...
return C.CString(x)
}
to return a pointer to an instance of a C string. Free the pointer when no longer needed.
$ go build -buildmode=c-shared -o _recap.so
$ python3 recap.py
50 33 25
$
recap.go
:
package main
import (
"C"
"strconv"
)
//export PrintAlg
func PrintAlg(debug bool) *C.char {
var b200 int = 0
var b300 int = 0
var b400 int = 0
var x string = "A"
if debug == true {
// extra
} else if debug == false {
for i := 1; i <= 100; i++ {
if i%4 == 0 && i%3 == 0 {
b200++
b300++
b400++
} else if i%4 == 0 && !(i%3 == 0) {
b400++
b200++
} else if i%2 == 0 && i%3 == 0 && !(i%4 == 0) {
b200++
b300++
} else if i%3 == 0 && !(i%2 == 0) && !(i%4 == 0) {
b300++
} else if i%2 == 0 && !(i%3 == 0) && !(i%4 == 0) {
b200++
} else if i%2 == 0 && i%3 == 0 && i%4 == 0 {
b200++
b300++
b400++
}
}
x = strconv.Itoa(b200) + " " + strconv.Itoa(b300) + " " + strconv.Itoa(b400)
}
return C.CString(x)
}
func main() {}
recap.py
:
import ctypes
recap = ctypes.cdll.LoadLibrary('./_recap.so')
printAlg = recap.PrintAlg
printAlg.argtypes = [ctypes.c_bool]
printAlg.restype = ctypes.c_void_p
free = recap.free
free.argtypes = [ctypes.c_void_p]
px = printAlg(False)
x = ctypes.string_at(px).decode('utf-8')
free(px)
print(x)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论