Wrappers [libraries.wrappers]
Prefer native Nim code when available.
C libraries and libraries that expose a C API may be used (including rust, C++, go).
Avoid C++ libraries.
Prefer building the library on-the-fly from source using {.compile.}. Pin the library code using a submodule or amalgamation.
The interop guide contains more information about foreing language interoperability.
Pros
- Wrapping existing code can improve time-to-market for certain features
- Maintenance is shared with upstream
- Build simplicity is maintained when
{.compile.}is used
Cons
- Often leads to unnatural API for
Nim - Constrains platform support
- Nim and
nimbletooling poorly supports 3rd-party build systems making installation difficult - Nim
C++support incomplete- Less test suite coverage - most of
Nimtest suite usesCbackend - Many core
C++features likeconst,&and&&difficult to express - in particular post-C++11code has a large semantic gap compared to Nim - Different semantics for exceptions and temporaries compared to
Cbackend - All-or-nothing - can't use
C++backend selectively forC++libraries
- Less test suite coverage - most of
- Using
{.compile.}increases build times, specially for multi-binary projects - use judiciously for large dependencies
Practical notes
- Consider tooling like
c2nimandnimteropto create initial wrapper - Generate a
.nimfile corresponding to the.hfile of the C project- preferably avoid the dependency on the
.hfile (avoid{.header.}directives unless necessary)
- preferably avoid the dependency on the
- Write a separate "raw" interface that only imports
Cnames and types as they're declared inC, then do convenience accessors on the Nim side- Name it
xxx_abi.nim
- Name it
- To use a
C++library, write aCwrapper first- See
llvmfor example
- See
- When wrapping a
Clibrary, consider ABI, struct layout etc