英文:
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{}
//被填充
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
}
英文:
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
}
</details>
# 答案1
**得分**: 3
API期望一个`float`数组,但你尝试创建的`[]*C.float`是一个指向`float`的指针数组。这些是不兼容的类型,这正是编译器所提示的。
好消息是,这些都是不必要的,因为Go的`[]float32`与C的`float[]`具有相同的布局兼容性,所以你可以直接将Go切片作为指向其第一个元素的指针传递给C函数。
floats := []float32{}
//填充切片
if !C.CalcModelPredictionSingle(
model.Handle,
(*C.float)(&floats[0]), // 将指向切片第一个元素的指针传递
C.size_t(len(floats)), // 传递切片长度
...
) {
return
}
请注意,在C中,`float[]`和`*float`是相同的东西。
<details>
<summary>英文:</summary>
The API is expecting an array of `float`s, but `[]*C.float` that you're trying to make is an array of pointers-to-`float`s. 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.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论