I have two files, module.go
and test.py
. My goal is to speed up some calculations that is done in python, but have an issue accessing array of integers in go.
module.go
JavaScript
x
11
11
1
package main
2
3
import "C"
4
5
//export Example
6
func Example(testArray []C.int) C.int {
7
return testArray[2]
8
}
9
10
func main() {}
11
and simple test file in python:
JavaScript
1
12
12
1
from ctypes import *
2
3
# Load compiled go module
4
lib = cdll.LoadLibrary("./gomodule.so")
5
# We are passing an array of 256 elements and recieving integer
6
lib.Example.argtypes = [c_int * 256]
7
lib.Example.restype = c_int
8
pyarr = [x for x in range(256)]
9
# Make C array from py array
10
arr = (c_int * len(pyarr))(*pyarr)
11
print lib.Example(arr)
12
After compiling go module with go build -buildmode=c-shared -o gomodule.so module.go
and fire up python file I got:
JavaScript
1
10
10
1
panic: runtime error: invalid memory address or nil pointer dereference
2
[signal SIGSEGV: segmentation violation code=0x1 addr=0x12 pc=0x7fb18b6e688c]
3
4
goroutine 17 [running, locked to thread]:
5
main.Example( )
6
/home/metro/go/src/github.com/golubaca/carinago/module.go:7
7
main._cgoexpwrap_53c1c00d0ad3_Example(0xa, 0x7fff33a2eac0, 0x7fff33a2ea70, 0x722a921de6cae100)
8
_cgo_gotypes.go:47 +0x1c
9
Aborted (core dumped)
10
I get that C array is different from Go, but can’t find any tutorial how to access it’s values without panic.
Advertisement
Answer
This is the idiomatic, efficient Go solution (avoid reflection).
module.go
:
JavaScript
1
14
14
1
package main
2
3
import "C"
4
5
import "unsafe"
6
7
//export Example
8
func Example(cArray *C.int, cSize C.int, i C.int) C.int {
9
gSlice := (*[1 << 30]C.int)(unsafe.Pointer(cArray))[:cSize:cSize]
10
return gSlice[i]
11
}
12
13
func main() {}
14
test.py
:
JavaScript
1
12
12
1
from ctypes import *
2
3
# Load compiled go module
4
lib = cdll.LoadLibrary("./gomodule.so")
5
# We are passing an array of 256 elements and receiving an integer
6
lib.Example.argtypes = [c_int * 256]
7
lib.Example.restype = c_int
8
pyarr = [x for x in range(256)]
9
# Make C array from py array
10
arr = (c_int * len(pyarr))(*pyarr)
11
print(lib.Example(arr, len(arr), 4))
12
Output:
JavaScript
1
5
1
$ go build -buildmode=c-shared -o gomodule.so module.go
2
$ python test.py
3
4
4
$
5