如何将Go数组的字符串转换为C字符串数组?

1ij*_*ijk 6 c arrays string go cgo

cgo在一个项目中使用,我想导出一个函数供使用.这是我想要实现的一个例子:

package csplit

import (
    "C"
    "strings"
)

//export Split
/* The Split function takes two C strings, the second of which represents
   a substring to split on, and returns an array of strings. Example:
       Split("1,2", ",") // gives ["1", "2"]
*/
func Split(original *C.char, split *C.char) []*C.char {
        goResult := strings.Split(C.GoString(original), C.GoString(split))
        cResult := make([]*C.char, len(goResult))

        for idx, substring := range goResult {
                cResult[idx] = C.CString(substring)
        }

        return cResult
}
Run Code Online (Sandbox Code Playgroud)

问题是返回类型是Go分配数据,而不是移入C堆.这恐慌:runtime error: cgo result has Go pointer

Jim*_*imB 9

您将返回在Go中分配的Go切片,并且是与C数组不同的结构.你需要在C中分配一个数组:

//export Split
func Split(original *C.char, split *C.char) **C.char {
    goResult := strings.Split(C.GoString(original), C.GoString(split))
    cArray := C.malloc(C.size_t(len(goResult)) * C.size_t(unsafe.Sizeof(uintptr(0))))

    // convert the C array to a Go Array so we can index it
    a := (*[1<<30 - 1]*C.char)(cArray)

    for idx, substring := range goResult {
        a[idx] = C.CString(substring)
    }

    return (**C.char)(cArray)
}
Run Code Online (Sandbox Code Playgroud)

  • @haiqus:对不起,我输入了一个错误,并且应该在malloc中包含一个sizeof(我当时想的是`char`而不是`char*`,如果我没有省略sizeof,这本来就很明显).我修改它以显示正确的malloc大小. (2认同)