在Go 1.6的CGo指针规则下,如何处理持有大缓冲区的void *参数列表

Suppose I'm interacting with a third party C library from Go that maintains some complicated data structure. It allows me to iterate over the data structure using an API that looks something like this:

typedef void (*callback)(double x, void *params);
iterate(int64_t start_idx, int64_t end_idx, callback f, void *params);

With the idea being that iterate loops over every index between start_idx and end_idx and calls f on every element in that range. If you wanted to read the data out of the complicated data structure and into an array, you would write something like this:

typedef struct buffer {
    double *data;
    int64_t i;
} buffer;

void read_callback(double x, void *params) {
    buffer *buf = (buffer*) params;
    buf->data[i] = x;
    buf->i++;
}

Now let's suppose that I wanted to wrap this API call in a Go function where the user passes the function a pre-allocated buffer. In Go 1.5, I might have done something like this:

func Read(startIdx, endIdx int64, data []float64) {
    buf := &C.buffer{}
    buf.data = unsafe.Pointer(&data[0])
    C.iterate(C.int64_t(startIdx), C.int64_t(endIdx),
        (C.callback)(C.read_callback), unsafe.Pointer(buf))
}

However, in Go 1.6 this is invalid. data is a Go-pointer and so is buf, meaning that the runtime panics to prevent a GC error. Allocating buf as a C-pointer is also not allowed. I think the intended way to handle something like this would be to allocate data as a C pointer, but I don't want to allocate a temporary array inside Read because these arrays are large enough that I can't hold two of them in memory at once (and even if I could, I wouldn't be able to deal with the heap fragmentation).

My current (very hacky) solutions are to either pass some of the data around as global variables or to pack i and the array length in the first element of array (and then to swap some data around at the end of the iteration). Is there a way for me to do this which is less terrible?