如何在go中将指针传递给切片到C函数

时间:2017-03-01 11:29:38

标签: c go cgo

背景:使用cgo从Golang调用C函数。

我想使用具有此签名的C函数:int f(int *count, char ***strs)。 它将修改countstrs的数据,这就是它使用指针的原因。 count的值是strs的长度; strs是一个字符串数组;返回值只是一个(布尔值)指示符,指示是否存在错误。

在golang中,我可以使用count成功传递和修改C.f((*C.int)(&count));使用[]string传递[]*C.char。示例代码如下:

/*
#include <stdio.h>
int f(int *c, char **str) {
    int i;
    printf("%d\n", *c);
    for (i = 0; i < *c; i++) {
        printf("%s\n", str[i]);
    }
    *c = (*c) + 1;
    return 1;
}
*/
import "C"
func go_f(strs []string) int {
    count := len(strs)
    c_count := C.int(count)

    c_strs := make([]*C.char, count)
    for index, value := range strs {
        c_strs[index] = C.CString(value)
        defer C.free(unsafe.Pointer(c_strs[index]))
    }

    err := C.f(&c_argc, (**C.char)(&c_argv[0]))
    return int(err)
}

如您所见,C函数目前为int f(int *c, char **str),但我想要的是int f(int *c, char ***str)

这就是说:我真正想要的是在C中启用对字符串数组的修改(例如调整大小)并将其转回Go字符串切片,这样我仍然可以在Go中使用它。

怎么做?我已经搜索并试验了一段时间,但没有运气。

1 个答案:

答案 0 :(得分:4)

Go切片既在Go中分配,又在C数组中分配不同的数据结构,因此您无法将其传递给C函数(cgo也会阻止您执行此操作,因为切片包含Go指针)

你需要在C中分配数组以便在C中操作数组。就像使用C.CString一样,你还需要跟踪释放外部数组的位置,特别是如果C函数可能会分配一个新的阵列。

SPOON
34