首页 > 解决方案 > 将 float32 的 Go 切片作为 C float[] 传递给 CGo

问题描述

我正在尝试使用 catboost 来预测一组浮点数。

CalcModelPredictionSingle它的文档中作为参数"floatFeatures - array of float features"https ://github.com/catboost/catboost/blob/master/catboost/libs/model_interface/c_api.h#L175

但是,当我尝试传递浮点数组时,出现此错误:

Cannot use type []*_Ctype_float as *_Ctype_float in assignment.

表示它期待一个浮动。我使用了错误的功能吗?

我正在使用 cgo,这是我的代码的一部分:

```
floats := []float32{}
//gets populated

floatsC := make([]*C.float, len(floats))
for i, v := range floats {
    floatsC[i] = (*C.float)(&v)
}

if !C.CalcModelPredictionSingle(
    model.Handle,
    ([]*C.float)(floatsC),
    ...
) {
    return
}

标签: cgocatboostcatboostregressor

解决方案


API 需要一个 s 数组float,但[]*C.float您尝试创建的是一个指向floats 的指针数组。这些是不兼容的类型,这正是编译器所说的。

好消息是这些都不是必需的,因为 Go[]float32与 C 布局兼容,float[]因此您可以将 Go 切片作为指向其第一个元素的指针直接传递给 C 函数。

floats := []float32{}
//gets populated
    
if !C.CalcModelPredictionSingle(
    model.Handle,
    (*C.float)(&floats[0]), // pass the pointer to the first slice element
    C.size_t(len(floats)),  // pass the slice length
    ...
) {
    return
}

请注意,在 C 中float[]*float是一回事。


推荐阅读