Wrapping C code is best done in two phases: one that expresses the C ABI in Nim 
terms - pretty much, this is what a header file does in C - you simply replace 
your .h file with a .nim file and change the syntax, adding appropriate Nim 
annotations like bycopy and so on. After this stage, the C header file is no 
longer needed, but should correspond 1:1 to the Nim file.

This part can often be automated to 80:ish% - the rest needs manual overrides 
for the vast majority of C headers. In my experience, the best tool out there 
for this is Nimterop - we use it on sqlite for example: 
<https://github.com/arnetheduck/nim-sqlite3-abi> .

I find nimterop to work better mainly because it has a much better C parser 
than c2nim, while it still knows about Nim quirks. The best feature it has it 
that it outputs a Nim file that you can further fine-tune.

The next stage of writing a wrapper is to create an interface that is pleasant 
to use from Nim - depending on the C library, this will be easy or hard, but 
above all, without this stage, you'll be writing C code effectively - this 
wrapper cannot be generated at all, but is almost equally important.

Automated solutions are nice at first look because they work for "hello world" 
type of code. Anyone using one should expect however that the wrapper will need 
further work as Nim is not a superset of C.

The final point is that just like you might accidentally mismatch C headers and 
the compiled libraries they reference, the same thing happens with Nim files - 
here, it's usually good to ensure that each version of the C library has its 
own Nim representation - currently, the nim standard library and community is 
fairly lax on this point which again makes simple cases simple - unfortunately 
it also makes hard cases nearly-impossible to figure out (ABI mismatches are 
among the most difficult bugs to reason about). This is where the separate ABI 
description comes in - if you have one of these for each version of the C 
library customized for that version in particular (including all field 
alignments and object sizes correct), the rest will usually work. 

Reply via email to