如何在Go中将指向切片的指针传递给C函数

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

我想使用具有以下签名的C函数:int f(int *count, char

***strs)。它会修改的数据countstrs,这就是为什么它使用指针,它们的原因。的值count是的长度strsstrs是一个字符串数组;返回值只是一个(布尔)指示符,用于指示是否存在错误。

在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中使用它。

这该怎么做?我搜索并尝试了一段时间,但没有运气。

回答:

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

您需要在C中分配数组才能操作C中的数组。就像使用C.CString一样,您还需要跟踪释放外部数组的位置,尤其是在C函数可能分配新数组的情况下。

cArray := C.malloc(C.size_t(c_count) * 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 index, value := range strs {

a[index] = C.CString(value)

}

err := C.f(&c_count, (***C.char)(unsafe.Pointer(&cArray)))

以上是 如何在Go中将指向切片的指针传递给C函数 的全部内容, 来源链接: utcz.com/qa/427830.html

回到顶部