如何将 go (array/slice/ist) 返回到 C 函数 hello.gohello.c

问题描述

我有调用 golang 函数的 C 代码。我可以为基元数据类型(int/float 等)执行此操作,但我想返回一些其他数据结构,如数组/列表/切片。 我在互联网上找不到任何解决方案。

寻求帮助。

想要返回字符串数据类型的数组/切片/列表。

解决方法

如果您提供其他信息,即您当前正在处理的示例代码,将会很有帮助。

Cgo documentation page所述:

不支持 Go 数组类型;使用 C 指针

这样做

hello.go

package main

// #include <stdlib.h>
import "C"

import "unsafe"

// StringSlice is a wrapper arround GoStringSlice to make it usable in C.
//export StringSlice
func StringSlice() **C.char {
    x := GoStringSlice()
    ret := C.malloc(C.size_t(len(x)) * C.size_t(unsafe.Sizeof(uintptr(0))))

    // convert to usable format so we are able to fill it with data
    pRet := (*[1<<30 - 1]*C.char)(ret)

    for i,item := range x {
        pRet[i] = C.CString(item)
    }

    return (**C.char)(ret)

}

func GoStringSlice() []string {
    return []string{
        "Hello","World",}
}

func main() {}

hello.c

#include <stdio.h>
#include "hello.h"

int main() {
    printf("Hello from C!\n");

    char **slice = StringSlice();
    int numItems = sizeof(slice) / sizeof(char *);

    printf("Number of items: %d\n",numItems+1);

    printf("String #0: %s\n",*slice);
    slice++;
    printf("String #1: %s\n",*slice);

    return 0;
}

您必须执行 go build -buildmode=c-archive hello.go,这将生成 hello.hhello.ahello.a 必须使用您的 C 代码编译:{{1​​}}。