gocgo

casting a cgo array into a slice


At the moment I do this for casting a CGO array of doubles into a slice of float64:

doubleSlc := [6]C.double{}

// Fill doubleSlc

floatSlc := []float64{float64(doubleSlc[0]), float64(doubleSlc[1]), float64(doubleSlc[2]),
                      float64(doubleSlc[3]), float64(doubleSlc[4]), float64(doubleSlc[5])}

Is there a less cumbersome way of doing the same thing? I suppose this can also be seen as a general way of casting between slices/arrays of different types in Go.


Solution

  • You have the normal and safe way of doing this:

    c := [6]C.double{ 1, 2, 3, 4, 5, 6 }
    fs := make([]float64, len(c))
    for i := range c {
            fs[i] = float64(c[i])
    }
    

    Or you could cheat unportably and do this:

    c := [6]C.double{ 1, 2, 3, 4, 5, 6 }
    cfa := (*[6]float64)(unsafe.Pointer(&c))
    cfs := cfa[:]
    

    If C.double and float64 are the same underlying type we can take a pointer to the C.double array, unsafely cast it to a pointer to a same size float64 array, then take a slice of that array.

    Of course it's called unsafe for a very good reason.