I am trying to pass 2d array from Go to some C function void foo(in **float, out *double). Since I want to have wrapper for this C function, I'd like that Go function has definition like func FooWrapper([][]float32) []float64. The easiest but not efficient implementation is allocating all memory through C that listed below:
func FooWrapper(values [][]float32) []float64 { totalObj := len(values) totalParams := len(values[0]) results := make([]float64, totalObj) ptrArrLength := uintptr(totalObj) * cPointerSize paramArrLength := uintptr(totalParams) * cFloatSize ptr := C.malloc(C.size_t(ptrArrLength + paramArrLength*uintptr(totalObj))) defer C.free(ptr) ptrSlice := unsafe.Slice((**C.float)(ptr), totalObj) for i, obj := range values { paramArrPtr := (*C.float)(unsafe.Add(ptr, ptrArrLength+uintptr(i)*paramArrLength)) ptrSlice[i] = paramArrPtr paramSlice := unsafe.Slice(paramArrPtr, totalParams) for j, param := range obj { paramSlice[j] = (C.float)(param) } } C.foo((**C.float)(ptr), (*C.double)(&results[0])) return results } Is that safe implementation? Can I pass pointer of result data? As far as I know, this pointer will be pinned because it passed to C function. But I want to allocate less memory just reusing Go memory, I've learned about runtime.Pinner that make pointer pinned until runtime.Pinner.Unpin() invocation. I tried to write another implementation using pinner: func FooWrapper(values [][]float32) []float64 { length := len(values) results := make([]float64, length) pinner := runtime.Pinner{} defer pinner.Unpin() arr := (**C.float)(C.malloc(C.size_t(uintptr(length) * cPointerSize))) defer C.free(unsafe.Pointer(arr)) slice := unsafe.Slice(arr, length) for i, v := range values { pinner.Pin(&v[0]) slice[i] = (*C.float)(&v[0]) } C.foo(arr, (*C.double)(&results[0])) return results } But, unfortunately, this code doesn't work runtime: pointer 0xc016ecbfc0 to unused region of span span.base()=0xc016eca000 span.limit=0xc016ecbfa0 span.state=1 fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?) Do I use runtime.Pinner wrong (as far as I know, I can pin slice data)? Or there is another error in this code. Are there some implementations for passing 3d (4d and so on) array to C function except for allocatiing and copying all data to C memory? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/82fd0ab7-0fa9-46cb-b752-699877478744n%40googlegroups.com.