Home > Software design >  Passing a Go slice of float32 to CGo as a C float[]
Passing a Go slice of float32 to CGo as a C float[]

Time:10-21

I'm trying to use catboost to predict for one array of floats.

In the documentation for CalcModelPredictionSingle it takes as param "floatFeatures - array of float features": https://github.com/catboost/catboost/blob/master/catboost/libs/model_interface/c_api.h#L175

However when I try to pass an array of floats, I get this error:

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

Indicating it's expecting a single float. Am I using the wrong function?

I am using cgo and this is part of my code:

```
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
}

CodePudding user response:

The API is expecting an array of floats, but []*C.float that you're trying to make is an array of pointers-to-floats. Those are incompatible types, which is exactly what the compiler is telling.

The good news is none of that is necessary as a Go []float32 is layout-compatible with a C float[] so you can pass your Go slice directly to the C function as a pointer to its first element.

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
}

Note that in C float[] and *float are the same thing.

  • Related