We call this nim-c-nim sandwich. How it works is that we compile nim-c and create the DLL with a basic C interface. Then we create another nim file (it kind of looks it was generated by c2nim) that does the export.
original nim function: proc simpleCall(a: int): int = ## Returns the integer passed in. return a Run c function signature: long long test_simple_call(long long a); Run nim's function DLL importer: proc test_simple_call(a: int): int {.importc: "test_simple_call", cdecl.} proc simpleCall*(a: int): int {.inline.} = result = test_simple_call(a) Run We do a function wrapper around the C function because some times one needs to convert from cstring to string, or other types, or insert exception handling. Some times its wrappers on both ends, to pass a string we convert it to cstring and then back to string. This allows programs using the DLL to use --gc:refc while DLL basically require use of --gc:arc or --gc:orc.