英文:
CGO getting a [][]float32 from C ** float
问题
我正在尝试使用一个具有C兼容头文件的C++库中的函数,它希望我传入一个4x4矩阵以供其填充。
我的Go函数定义如下:
func GetMatrix(matrix []float32)
而C头文件中的定义如下:
void getMatrix(const float **matrix)
我尝试使用C.GoBytes来获取一个字节数组,但是从那里开始,我有点迷失,因为我必须从字节数组转换为指针数组,然后再转换为字节数组,最后转换为浮点数数组。
至少我认为我需要这样做。
我看到过一些代码示例,用C数组数据替换了底层的Go切片,但我相信在这些情况下,Go的垃圾回收器不会收集它们。理想情况下,matrix [][]float32应该像普通的Go切片一样工作。
编辑:
文档是错误的,底层的C类型实际上是一个包含16个元素的浮点数数组。
所以问题变成了,我可以使用指向数组的指针的指针来使用C.GoBytes吗?如果可以,如何从[]byte获取[]float32?
英文:
I'm trying to call a function in a C++ library with a C compatible header, which wants me to pass in a 4x4 matrix for it to populate.
My Go function definition looks like this:<strike>
func GetMatrix(matrix [][]float32)
</strike>
func GetMatrix(matrix []float32)
And the c header defines it like this:
void getMatrix(const float **matrix)
<strike>I've tried using C.GoBytes to get a byte array, but then from there I'm a little lost as I have to go from a byte array to an array of pointers, which I then again convert to an array of bytes, and eventually an array of floats.
At least I think that's what I need to do.
I've seen examples of code replacing the underlying Go slice with the C array data, but I believe in those cases, the Go GC won't collect them. Ideally matrix [][]float32 would behave like a normal Go slice.</strike>
Edit:
The documentation was incorrect, and the underlying C type is actually a 16 element float array.
So the question then becomes, can I use C.GoBytes with a pointer, to a pointer of an array, and if so, how do I get a []float32 from []byte?
答案1
得分: 1
Edited 这打印出正确的东西
package main
/*
#include <stdio.h>
void getMatrix(const float **matrix){
float *m = (float *)matrix;
int i;
for(i = 0; i<9; i++) {
printf("%f\n",m[i]);
}
}
*/
import "C"
import "unsafe"
func main() {
a := []float32{1,2,3,4,5,6,7,8,9}
C.getMatrix((**C.float)(unsafe.Pointer(&a[0])))
}
英文:
Edited This prints the right stuff
<!-- language: lang-go -->
package main
/*
#include <stdio.h>
void getMatrix(const float **matrix){
float *m = (float *)matrix;
int i;
for(i = 0; i<9; i++) {
printf("%f\n",m[i]);
}
}
*/
import "C"
import "unsafe"
func main() {
a := []float32{1,2,3,4,5,6,7,8,9}
C.getMatrix((**C.float)(unsafe.Pointer(&a[0])))
}
答案2
得分: 1
这是一种将指向Go数组的指针传递给C函数的方法,以便C函数可以填充它:
package main
/*
#include <stdio.h>
void getMatrix(float *m) {
int i;
for(i = 0; i < 16; i++) {
m[i] = (float)i;
}
}
*/
import "C"
import "fmt"
func main() {
var a [16]float32
C.getMatrix((*C.float)(&a[0]))
fmt.Println(a)
}
英文:
Here's a way to pass a pointer to a go array to a C function, so the C function can populate it:
package main
/*
#include <stdio.h>
void getMatrix(float *m) {
int i;
for(i = 0; i < 16; i++) {
m[i] = (float)i;
}
}
*/
import "C"
import "fmt"
func main() {
var a [16]float32
C.getMatrix((*C.float)(&a[0]))
fmt.Println(a)
}
答案3
得分: 0
我认为你需要使用的Go类型是
*[16]*float32
无论如何,[][]float32永远不会与C的**float兼容。
英文:
I think that the Go type you'll have to use is
*[16]*float32
In any case the [][]float32 is never going to be compatible with **float of C.
答案4
得分: 0
Pointer to 4x4 array of arrays has type *[4]*[4]float32
.
英文:
Pointer to 4x4 array of arrays has type *[4]*[4]float32
.
答案5
得分: 0
package main
import "C"
import "unsafe"
func main() {
// 创建一个连续的16个元素的数组,但按照描述的方式组织它。
a := [4][4]float32{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16},
}
m := &a // 取指针。
C.getMatrix((**C.float)(unsafe.Pointer(&m))) // 取句柄并传递。
}
英文:
Extending on the answer provided by Inuart:
package main
/*
#include <stdio.h>
void getMatrix(const float **matrix){
float *m = (float *)*matrix;
int i;
for(i = 0; i<16; i++) {
printf("%f\n",m[i]);
}
}
*/
import "C"
import "unsafe"
func main() {
// Create the contiguous 16 element array, but organise it how it is described.
a := [4][4]float32{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16},
}
m := &a // Take the pointer.
C.getMatrix((**C.float)(unsafe.Pointer(&m))) // Take the handle and pass it.
}
This give you the handle behaviour that you seem to be asking for and has the advantage that the shape of the data in Go is as it appears to be asked for by the C API - there's no need to eschew the ease of use and safety of Go, just because you are interfacing with C.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论