将[] float32转换为C * float

时间:2016-11-17 01:05:22

标签: go cgo

我想将指针传递给slice [] float32的第一个元素到C变量,但不知何故我无法弄清楚如何。

C代码:

typedef struct
{   const float *data_in ;
    float    *data_out ;

} SRC_DATA ;

转到:

mySlice := make([]float32, 20)
foo := C.SRC_DATA{}
foo.data_in = *C.float(&mySlice[0]) // here the program breaks

据我所知,应该可以直接将指针传递给切片中的第一个元素,而不使用unsafe.Pointer()。

然后C函数将在切片上迭代(已知长度)。

任何提示都表示赞赏!

1 个答案:

答案 0 :(得分:2)

  1. 您需要使用C.float类型的切片而不是float32
  2. package main
    /*
    #include <stdio.h>
    void test(float *in) {
        printf("C %f %f\n", in[0], in[1]);
    }
    */
    import "C"
    
    func main() {
        in := []C.float{1.23, 4.56}
        C.test(&in[0]) // C 1.230000 4.560000
    }
    
    1. Go不允许将Go指针存储在传递给Cgo的Go分配结构中:
    2. package main
      /*
      #include <stdio.h>
      typedef struct {
              float *in;
              float *out;
      } SRC_DATA;
      
      void test(SRC_DATA *data) {
          printf("C %f %f\n", data->in[0], data->in[1]);
          data->out[0] = 8.8;
          data->out[1] = 9.9;
      }
      */
      import "C"
      import "fmt"
      
      func main() {
          in := []C.float{1.23, 4.56}
          out := make([]C.float, 2)
          data := &C.SRC_DATA{in: &in[0], out: &out[0]}
          C.test(data) // panic: runtime error: cgo argument has Go pointer to Go pointer
          fmt.Println("Go", out)
      }
      

      但是你可以用C:

      创建一个辅助函数
      package main
      /*
      #include <stdio.h>
      typedef struct {
              float *in;
              float *out;
      } SRC_DATA;
      
      void test(SRC_DATA *data) {
          printf("C %f %f\n", data->in[0], data->in[1]);
          data->out[0] = 8.8;
          data->out[1] = 9.9;
      }
      
      void test_helper(float *in, float *out) {
          SRC_DATA data;
          data.in = in;
          data.out = out;
          test(&data);
      }
      */
      import "C"
      import "fmt"
      
      func main() {
          in := []C.float{1.23, 4.56}
          out := make([]C.float, 2)
          C.test_helper(&in[0], &out[0]) // C 1.230000 4.560000
          fmt.Println("Go", out) // Go [8.8 9.9]
      }
      

      或者,您可以在C:

      中分配和释放SRC_DATA结构
      package main
      /*
      #include <stdio.h>
      #include <stdlib.h>
      typedef struct {
              float *in;
              float *out;
      } SRC_DATA;
      
      void test(SRC_DATA *data) {
          printf("C %f %f\n", data->in[0], data->in[1]);
          data->out[0] = 8.8;
          data->out[1] = 9.9;
      }
      
      SRC_DATA *alloc_src_data() {
          return (SRC_DATA*)malloc(sizeof(SRC_DATA));
      }
      
      void free_src_data(SRC_DATA *p) {
          free(p);
      }
      */
      import "C"
      import "fmt"
      
      
      func main() {
          in := []C.float{1.23, 4.56}
          out := make([]C.float, 2)
          data := C.alloc_src_data()
          defer C.free_src_data(data)
          data.in = &in[0]
          data.out = &out[0]
          C.test(data)  // C 1.230000 4.560000
          fmt.Println("Go", out)  // Go [8.8 9.9]
      }