'panic: runtime error: cgo result has Go pointer
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?
Solution 1:[1]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
