为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
幕布斯7119047 2021-12-27 10:50:23
我有一个这样的 C 函数double* c_func(int n_rows) {  double result[n_rows];  for (int i = 0; i < n_rows; ++i) {    result[i] = (double)i;  }  return result;}我使用这个 Go 函数来处理 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}这有时有效,但有时无效。当它不起作用时,它返回如下内容:[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]对我来说这看起来有点记忆问题......我不确定这是否是在 Go 中处理从 C 返回的双数组的正确方法。如果是,如何解决问题(偶尔发生)。如果不是,处理从 C 返回的双数组的正确方法是什么?谢谢。
查看完整描述

2 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

在 C 中,您返回的那个指针将是陈旧的。您需要像 double *result = calloc(sizeof(double), nrows) 一样分配表——这也需要有一种释放内存的方法。


查看完整回答
反对 回复 2021-12-27
?
白板的微信

TA贡献1883条经验 获得超3个赞

好的,所以我想出了一个简单的方法来实现这一目标。


我们首先使用calloc为数组分配内存:


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;

}

之后,我们只需在 Go 中将数据转换为正确的类型。诀窍是使用C.free释放从 C 端分配的内存。


// 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

}


查看完整回答
反对 回复 2021-12-27
  • 2 回答
  • 0 关注
  • 233 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信