If pointer type points to an array, `ptr UncheckedArray[cdouble]` (or `ptr array[3, cdouble]` if array size is fixed) is better than `ptr cdouble`.
Example runnable code: import std/strformat {.emit:""" typedef void (*fptr_f) (double, double *, double *, void *); void foo(fptr_f f, double *y, void *_data); void foo(fptr_f f, double *y, void *_data) { double ydot[3]; f(123.0, y, ydot, _data); printf("In C function\n"); printf("ydot = [%f, %f, %f]\n", ydot[0], ydot[1], ydot[2]); } """.} type fptr_f = proc(t: cdouble; y: ptr UncheckedArray[cdouble]; ydot: ptr UncheckedArray[cdouble]; data: pointer) {.cdecl.} proc foo(f: fptr_f; y: ptr UncheckedArray[cdouble]; data: pointer): void {.importc: "foo".} proc nimCallback(t: cdouble; y: ptr UncheckedArray[cdouble]; ydot: ptr UncheckedArray[cdouble]; data: pointer) {.cdecl.} = echo "In nimCallback" echo &"t = {t}" echo &"y = [{y[0]}, {y[1]}, {y[2]}]" for i in 0..2: ydot[i] = y[i] var y = [cdouble 1.0, 2.0, 3.0]; foo(nimCallback, cast[ptr UncheckedArray[cdouble]](y[0].addr), nil) Run