How to pass pointer to slice on function C in go

Background: using cgo to call C functions from Golang.

I want to use a C function that has this signature: int f(int *count, char ***strs). It will modify the data countand strstherefore it uses a pointer to it. The value countis equal to the length strs; strs- an array of strings; the return value is just a (logical) indicator that indicates whether there is an error or not.

In golang, I can successfully pass and modify countwith C.f((*C.int)(&count)); pass []stringwith []*C.char. Sample code is as follows:

/*
#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)
}

As you can see, the C function is currently int f(int *c, char **str), but I would like to int f(int *c, char ***str).

, (, ) C Go, Go.

? , .

+4
1

A Go slice 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)))
+4

Source: https://habr.com/ru/post/1671137/


All Articles