douzinei6926 2018-11-10 11:44
浏览 219
已采纳

在Golang中访问C数组

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

package main

import "C"

//export Example
func Example(testArray []C.int) C.int {
    return testArray[2]
}

func main() {}

and simple test file in python:

from ctypes import *

# Load compiled go module
lib = cdll.LoadLibrary("./gomodule.so")
# We are passing an array of 256 elements and recieving integer
lib.Example.argtypes = [c_int * 256]
lib.Example.restype = c_int
pyarr = [x for x in range(256)]
# Make C array from py array
arr = (c_int * len(pyarr))(*pyarr)
print lib.Example(arr)

After compiling go module with go build -buildmode=c-shared -o gomodule.so module.go and fire up python file I got:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x12 pc=0x7fb18b6e688c]

goroutine 17 [running, locked to thread]:
main.Example(...)
        /home/metro/go/src/github.com/golubaca/carinago/module.go:7
main._cgoexpwrap_53c1c00d0ad3_Example(0xa, 0x7fff33a2eac0, 0x7fff33a2ea70, 0x722a921de6cae100)
        _cgo_gotypes.go:47 +0x1c
Aborted (core dumped)

I get that C array is different from Go, but can't find any tutorial how to access it's values without panic.

  • 写回答

2条回答 默认 最新

  • duanmengsuo9302 2018-11-10 19:27
    关注

    This is the idiomatic, efficient Go solution (avoid reflection).

    module.go:

    package main
    
    import "C"
    
    import "unsafe"
    
    //export Example
    func Example(cArray *C.int, cSize C.int, i C.int) C.int {
        gSlice := (*[1 << 30]C.int)(unsafe.Pointer(cArray))[:cSize:cSize]
        return gSlice[i]
    }
    
    func main() {}
    

    test.py:

    from ctypes import *
    
    # Load compiled go module
    lib = cdll.LoadLibrary("./gomodule.so")
    # We are passing an array of 256 elements and receiving an integer
    lib.Example.argtypes = [c_int * 256]
    lib.Example.restype = c_int
    pyarr = [x for x in range(256)]
    # Make C array from py array
    arr = (c_int * len(pyarr))(*pyarr)
    print lib.Example(arr, len(arr), 4)
    

    Output:

    $ go build -buildmode=c-shared -o gomodule.so module.go
    $ python test.py
    4
    $ 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用MATLAB进行余弦相似度计算加速
  • ¥15 服务器安装php5.6版本
  • ¥15 我想用51单片机和数码管做一个从0开始的计数表 我写了一串代码 但是放到单片机里面数码管只闪烁一下然后熄灭
  • ¥20 系统工程中,状态空间模型中状态方程的应用。请猛男来完整讲一下下面所有问题
  • ¥15 我想在WPF的Model Code中获取ViewModel Code中的一个参数
  • ¥15 arcgis处理土地利用道路 建筑 林地分类
  • ¥20 使用visual studio 工具用C++语音,调用openslsx库读取excel文件的sheet问题
  • ¥100 寻会做云闪付tn转h5支付链接的技术
  • ¥15 DockerSwarm跨节点无法访问问题
  • ¥15 使用dify通过OpenAI 的API keys添加OpenAI模型时报了“Connection Error”错误