Main import file to write wrappers. Each compileTime proc must be used in a compile time context, eg using:
static: cAddStdDir()
Procs
proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
-
Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.
Examples:
static : cSkipSymbol @["proc1", "Type2"]
proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
-
Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().
This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().
proc cDebug() {...}{.compileTime, raises: [], tags: [].}
- Enable debug messages and display the generated Nim code
proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
-
Disable caching of generated Nim code - useful during wrapper development
If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.
nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.
proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
-
Add directory dir to the search path used in calls to cSearchPath().
Examples:
import paths, os static : cAddSearchDir testsIncludeDir() doAssert cSearchPath("test.h").existsFile
proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [].}
-
Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()
Examples:
static : cAddStdDir() import os doAssert cSearchPath("math.h").existsFile
Macros
macro cOverride(body): untyped
-
When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.
For example:
int svGetCallerInfo(const char** fileName, int *lineNumber);
This might map to:
proc svGetCallerInfo(fileName: ptr cstring; lineNumber: var cint)
Whereas it might mean:
cOverride: proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint)
Using the cOverride() block, nimterop can be instructed to skip over svGetCallerInfo(). This works for procs, consts and types.
macro cPlugin(body): untyped
-
When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
proc onSymbol(sym: var Symbol) {.exportc, dynlib.}
onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.
Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.
Symbol types can be any of the following:
- nskConst for constants
- nskType for type identifiers, including primitive
- nskParam for param names
- nskField for struct field names
- nskEnumField for enum (field) names, though they are in the global namespace as nskConst
- nskProc - for proc names
nimterop/plugins is implicitly imported to provide access to standard plugin facilities.
Examples:
cPlugin: import strutils proc onSymbol*(sym: var Symbol) {...}{.exportc, dynlib.} = sym.name = sym.name.strip(chars = {'_'})
Examples:
cPlugin: import strutils proc onSymbol*(sym: var Symbol) {...}{.exportc, dynlib.} = if sym.kind == nskProc and sym.name.contains("SDL_"): sym.name = sym.name.replace("SDL_", "")
macro cDefine(name: static string; val: static string = ""): untyped
- #define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".}
macro cIncludeDir(dir: static string): untyped
- Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation.
macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
-
Compile and link C/C++ implementation into resulting binary using {.compile.}
path can be a specific file or contain wildcards:
cCompile("file.c") cCompile("path/to/*.c")
mode recursively searches for code files in path.
c searches for *.c whereas cpp searches for *.C *.cpp *.c++ *.cc *.cxx
cCompile("path/to/dir", "cpp")
exclude can be used to exclude files by partial string match. Comma separated to specify multiple exclude strings
cCompile("path/to/dir", exclude="test2.c")
macro cImport(filename: static string; recurse: static bool = false): untyped
-
Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.
recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()