英文:
convert a []float32 to C *float
问题
我想将一个切片 []float32 的第一个元素的指针传递给一个 C 变量,但是我不知道该怎么做。
C 代码:
typedef struct
{
const float *data_in;
float *data_out;
} SRC_DATA;
Go 代码:
mySlice := make([]float32, 20)
foo := C.SRC_DATA{}
foo.data_in = (*C.float)(&mySlice[0]) // 这里程序出错
据我所了解,应该可以直接将切片中的第一个元素的指针从 Go 传递给 C,而不需要使用 unsafe.Pointer()。
然后,C 函数将遍历该切片(长度已知)。
如果有任何提示,我将不胜感激!
英文:
I want to pass the pointer to the first element of a slice []float32 to a C variable, but somehow I can't figure out how.
C Code:
typedef struct
{ const float *data_in ;
float *data_out ;
} SRC_DATA ;
Go:
mySlice := make([]float32, 20)
foo := C.SRC_DATA{}
foo.data_in = *C.float(&mySlice[0]) // here the program breaks
As far as I have understood, it should be possible to pass directly a pointer to the first element in the slice from Go to C, without using unsafe.Pointer().
The C function will then iterate over the slice (length known).
Any hints are appreciated!
答案1
得分: 3
- 你需要使用
C.float
类型的切片而不是float32
类型的切片:
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
}
- Go不允许将Go指针存储在传递给Cgo的Go分配的结构中:
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]
}
英文:
- You need to use a slice of
C.float
type instead offloat32
:
<!-- language: go -->
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
}
- Go doesn't allow to store a Go pointer in a Go allocated structure passed to Cgo:
<!-- language: go -->
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)
}
But you can create a helper function in C:
<!-- language: go -->
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]
}
Alternatively you can allocate and free SRC_DATA
structure in C:
<!-- language: go -->
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]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论