dongye1942 2016-03-19 07:01
浏览 197
已采纳

Cgo:如何将双数组从C返回到Go

I got a C function like this

double* c_func(int n_rows) {
  double result[n_rows];
  for (int i = 0; i < n_rows; ++i) {
    result[i] = (double)i;
  }
  return result;
}

And I use this Go function to process the C double:

// convert C double pointer to float64 slice ...
func doubleToFloats(in *C.double, length int) []float64 {
    out := make([]float64, length, length)

    start := unsafe.Pointer(in)
    size := unsafe.Sizeof(C.double(0))
    for i := 0; i < length; i++ {
        val := *(*C.double)(unsafe.Pointer(uintptr(start) + size*uintptr(i)))
        out[i] = float64(val)
    }
    return out
}

This sometimes works but sometimes not. When it not works, it return something like this:

[0 1 2 3 4 5 6 7 8 9 10 2.53e-321 3.32018606e-316 4.24664374149e-312 4.24399158193e-312 1.1383e-320 3.31882387e-316 3.71924634e-316 3.31885594e-316 3.71924634e-316 5e-324 0 4.6950308e-316 4.24664374149e-312 3.7175681e-316 3.3200616e-316]

which looks like somewhat memory issue to me...

I'm not sure if this is the correct way to handle returned double array from C in Go. If yes, how to fix the problem (which occurs ocassionally). If no, what is the correct way to handle returned double array from C?

Thanks.

  • 写回答

2条回答 默认 最新

  • dtk31564 2016-03-19 14:46
    关注

    OK, so I figured out a simple way to achieve this.

    We first use calloc to allocate memory for the array:

    double* c_func(int n_rows) {
        double* result;
        result = calloc(n_rows, sizeof(double));
        for (int i = 0; i < n_rows; ++i) {
            result[i] = (double)i;
        }
        return result;
    }
    

    and after that, we simply convert the data into proper type in Go. The trick is to use C.free to free the memory allocated from C side.

    // convert C double pointer to float64 slice ...
    func doubleToFloats(in *C.double, size int) []float64 {
        defer C.free(unsafe.Pointer(in))
        out := (*[1 << 30]float64)(unsafe.Pointer(in))[:size:size]
        return out
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器