如何让cgo返回数组到c?

时间:2017-10-10 09:19:08

标签: c go cgo

我正在使用golang致电c,我想要返回string arrayint array,我这样做:

package main

import "C"
//export Seg
func Seg(input *C.char, segs *[]*C.char, tags *[]int) (errChars *C.char) {
  count := 10
  segs_ := make([]*C.char, 10, 10)
  for i:=0; i<count; i++ {
    segs_[i] = C.CString("aaaaaa")
  }
  segs = &segs_
  tags_ := make([]int, count)
  for i:=0; i<count; i++ {
    tags_[i] = i
  }
  tags = &tags_
  return
}
func main() {}

使用

构建
go build -o libacrf.so -buildmode=c-shared clib.go

这样称呼:

#include <stdio.h>
#include <stdlib.h>

#include "libacrf.h"

int main(int argc, char *argv[])
{
    GoSlice *segs, *tags;
    char* err;
    err = Seg("hahahhaha", segs, tags);
    if (err != NULL) {
        fprintf(stderr, "error: %s\n", err);
        free(err);
        return 1;
    }
    printf("%llu\n", (*tags).len); // it should be 10, but it is not right now

    return 0;
}

但问题是我无法从golang获得真正的结果。

2 个答案:

答案 0 :(得分:2)

这与C没有任何关系,你要覆盖<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!-- inject:css --> <!-- endinject --> </head> tags指针值的副本,而不是分配新的切片值; 。先在Go中做一个例子,看看你正在做什么。 https://play.golang.org/p/EQWRiqVwqm

为了将segs值分配给指针,语法应为

_tags

答案 1 :(得分:0)

我认为这是因为您负责所有C端数据的内存管理。 在C GoSlice中只有typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;,在您的示例中,您只是将未初始化的指针传递给GoSlice:

 GoSlice *segs, *tags; //here
 char* err;
 err = Seg("hahahhaha", segs, tags);

因此,您可以在此内存位置进行远程操作。 虽然Go不会从c代码管理你的内存块,但它也不会设置len字段。虽然上述所有内容都只是假设(我对Go不太了解)支持我的假设的一些证据将是这种修改:

int main(int argc, char *argv[])
{

GoInt data[10] = {77, 12, 5, 99, 28, 23, 33,33,33,33};
GoSlice segs_d = {data, 10, 10};
GoInt data2[10] = {77, 12, 5, 99, 28, 23, 33,33,33,33};
GoSlice tags_d = {data2, 10, 10};

GoSlice *segs, *tags;

segs= &segs_d;
tags= &tags_d;

char* err;
err = Seg("hahahhaha", segs, tags);
if (err != NULL) {
    fprintf(stderr, "error: %s\n", err);
    free(err);
    return 1;
}
printf("%llu\n", (*tags).len); // it should be 10, but it is not right now

return 0;
}