I am trying to call Nim code from C++. Specifically, a function that takes an anonymous function.
I have the following code in Nim:
proc test*(a: proc()) {.exportc.} = a()
which I compile to a static library. I then link it to my C++ executable and attempt to define the function with
extern "C" test(void a(void);
and call it with
void anon() { printf("hello"); }
...
test(anon)
Everything compiles fine, but when I run the program, it crashes.
By default, Nim will compile the anonymous proc types as closures represented by a pair of a C function pointer and a void pointer to a structure holding all of the local variables captured by the closure. It will look like this in the generated code:
typedef struct {
N_NIMCALL_PTR(void, ClP_0) (void* ClE_0);
void* ClE_0;
} tyProc_XXXXXX;
So, to solve the problem you must modify the extern "C" definition of the test function in the C code to accept a compatible structure type. Alternatively, you can ask Nim to compile the proc argument to a regular C function by adding the cdecl pragma to the proc type:
proc test*(a: proc() {.cdecl.}) {.exportc.} = a()
For the full list of calling conventions supported by Nim, check out the section on proc types in the Nim manual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With