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

huangapple go评论111阅读模式
英文:

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,以下是我的代码的一部分:

  1. floats := []float32{}
  2. //被填充
  3. floatsC := make([]*C.float, len(floats))
  4. for i, v := range floats {
  5. floatsC[i] = (*C.float)(&v)
  6. }
  7. if !C.CalcModelPredictionSingle(
  8. model.Handle,
  9. ([]*C.float)(floatsC),
  10. ...
  11. ) {
  12. return
  13. }
英文:

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:

  1. ```
  2. floats := []float32{}
  3. //gets populated
  4. floatsC := make([]*C.float, len(floats))
  5. for i, v := range floats {
  6. floatsC[i] = (*C.float)(&v)
  7. }
  8. if !C.CalcModelPredictionSingle(
  9. model.Handle,
  10. ([]*C.float)(floatsC),
  11. ...
  12. ) {
  13. return
  14. }
  1. </details>
  2. # 答案1
  3. **得分**: 3
  4. API期望一个`float`数组,但你尝试创建的`[]*C.float`是一个指向`float`的指针数组。这些是不兼容的类型,这正是编译器所提示的。
  5. 好消息是,这些都是不必要的,因为Go的`[]float32`与C的`float[]`具有相同的布局兼容性,所以你可以直接将Go切片作为指向其第一个元素的指针传递给C函数。
  6. floats := []float32{}
  7. //填充切片
  8. if !C.CalcModelPredictionSingle(
  9. model.Handle,
  10. (*C.float)(&floats[0]), // 将指向切片第一个元素的指针传递
  11. C.size_t(len(floats)), // 传递切片长度
  12. ...
  13. ) {
  14. return
  15. }
  16. 请注意,在C中,`float[]`和`*float`是相同的东西。
  17. <details>
  18. <summary>英文:</summary>
  19. The API is expecting an array of `float`s, but `[]*C.float` that you&#39;re trying to make is an array of pointers-to-`float`s. Those are incompatible types, which is exactly what the compiler is telling.
  20. 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.
  21. floats := []float32{}
  22. //gets populated
  23. if !C.CalcModelPredictionSingle(
  24. model.Handle,
  25. (*C.float)(&amp;floats[0]), // pass the pointer to the first slice element
  26. C.size_t(len(floats)), // pass the slice length
  27. ...
  28. ) {
  29. return
  30. }
  31. Note that in C `float[]` and `*float` are the same thing.
  32. </details>

huangapple
  • 本文由 发表于 2021年10月19日 23:15:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/69633493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定