This works:
type
closureFunc = proc(a: int, b: int, data: pointer) {.cdecl.}
proc myFunc(a, b: int, f: closureFunc) =
f(a, b, nil)
var
cnt = 0
clo = proc(a: int, b: int,c: pointer) {.cdecl.} =
cnt += 1
proc mainFunc() =
myFunc(1, 2, closureFunc(clo))
but this doesn't:
type
closureFunc = proc(a: int, b: int, data: pointer) {.cdecl.}
proc myFunc(a, b: int, f: closureFunc) =
f(a, b, nil)
proc mainFunc() =
var
cnt = 0
clo = proc(a: int, b: int,c: pointer) {.cdecl.} =
cnt += 1
myFunc(1, 2, closureFunc(clo))
Is there a way to make the second example work with the local 'clo' proc?There isn't a way at the moment to have a closure use the cdecl calling convention, primarily because it would make calling closures rather complicated.
As it stands, all closures must have the 'closure' calling convention outlined here. Whereas normal procedures can be represented by a single pointer, closures must be represented by two pointers - one for the raw closure procedure, and one for the environment that a closure captures (variables referenced from the outer scope, etc). When called, the compiler passes in the closure environment as part of the parameters to the raw function, and the raw function references the data contained in the environment.
In this way, the closure calling convention is really a pseudo-convention, as it doesn't dictate the calling convention of the raw function (which is currently the default calling convention for the given backend, I think). It's possible (but not currently implemented) to change the calling convention of the raw function pointer, but this leads to complications (now you have ~6 more calling conventions floating around, when combined with the closure convention).