将 float32 的 Go 切片作为 C float[] 传递给 CGo

Passing a Go slice of float32 to CGo as a C float[]

我正在尝试使用 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
}

API 需要一个 float 的数组,但是您要创建的 []*C.float 是一个指向 float 的指针数组.这些是不兼容的类型,这正是编译器告诉我们的。

好消息是 none 这是必要的,因为 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 是同一回事。