CGO从C **浮点数得到[] [] float32

时间:2012-05-23 21:33:15

标签: go

我正在尝试在C ++库中调用一个带有C兼容标头的函数,它希望我传入一个4x4矩阵来填充它。

我的Go功能定义如下所示:

func GetMatrix(matrix [][]float32)

<击>

func GetMatrix(matrix []float32)

c标头定义如下:

void getMatrix(const float **matrix)

我已经尝试过使用C.GoBytes获取一个字节数组,但是从那里我有点迷失,因为我必须从一个字节数组转到一个指针数组,然后我再次转换到一个字节数组,最后是一个浮点数组。

至少我认为这就是我需要做的。

我见过用C数组替换底层Go切片的代码示例,但我相信在这些情况下,Go GC不会收集它们。理想情况下,matrix [] [] float32的行为类似于普通的Go切片。

修改 文档不正确,底层的C类型实际上是一个16元素的浮点数组。

那么问题就变成了,我可以使用带有指针的C.GoBytes,指向数组的指针,如果是这样,我如何从[] byte获得[] float32?

5 个答案:

答案 0 :(得分:1)

已修改这会打印正确的内容

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])))
}

答案 1 :(得分: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)
}

答案 2 :(得分:0)

我认为您必须使用的Go类型是

*[16]*float32

在任何情况下,[] [] float32永远不会与C的**浮点兼容。

答案 3 :(得分:0)

指向4x4数组数组的指针的类型为*[4]*[4]float32

答案 4 :(得分:0)

扩展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.
}

这为您提供了您似乎要求的句柄行为,并且具有以下优势:Go中的数据形状与C API似乎要求的一样 - 无需避免使用的简便性Go的安全性,只因为你正在与C接口。