Nim package for easy shared library loading.
Usage
dlgencalls "somelib", paths: # proc and var definitions
dlgencalls creates three procs: proc open_somelib_library(): bool, proc close_somelib_library() and proc last_somelib_error().
Open proc
The open proc tries to load shared library defined in paths and loads all symbols defined in body. Paths may be either single string or an array of strings. Subsequent calls are ignored.
The open proc returns true on success or false on error (no library found, one of symbols not found).
Procs and variables marked with unchecked pragma do not cause open function to faile and are set to nil.
Allowed definitions in body:
- proc: proc (a: cint): cint
- var: var a: cint
- where statement
Not allowed in body:
- export marker * in variable; all functions and variables are exported by default
- multiple variables in single var statement; use single var statement per variable
Allowed proc pragmas:
- {.importc: "source_name".} - used when original name is invalid in Nim or you want to change it
- {.unchecked.} - used when definiton is optional - the proc pointer is set to nil if no such proc is found in library
- {.varargs.} - used when proc takes varargs
Allowed var pragmas:
- {.importc: "source_name".} - used when original name is invalid in Nim or you want to change it
- {.unchecked.} - used when defintion is optional
All other proc/var pragmas are ignored.
Close proc
The close proc unloads the shared library. All symbols loaded are set to nil. Subsequent calls are ignored.
Error proc
The error proc returns a human-readable string describing the most recent error that occured from a call to open_name_library() or empty string on no error.
The returned string does not include a trailing newline.
Example
Source:
import dlutils # Create open_math_library, close_math_library, last_math_error # and proc/var symbols defined in body. dlgencalls "math", ["libm.so", "libm.so.6"]: # Required proc. open_math_library returns false if not found. proc cbrt (x: cdouble): cdouble # Optional proc. open_math_library sets sqrt to nil if not found. proc sqrt (x: cdouble): cdouble {.unchecked.} # Function "sqrtf" imported as "sqrt2". proc sqrt2 (x: cfloat): cfloat {.importc: "sqrtf".} # Required var of type ptr cint. var reqvar: cint # Optional var of type ptr clong. var optvar {.unchecked.}: clong
Generated code:
import std/dynlib var math_handle: LibHandle = nil var cbrt*: proc (x, y: cdouble): cdouble {.cdecl, gcsafe, raises: [].} = nil var sqrt*: proc (x, y: cdouble): cdouble {.cdecl, gcsafe, raises: [].} = nil var sqrt2*: proc (x, y: cfloat): cfloat {.cdecl, gcsafe, raises: [].} = nil var reqvar*: ptr cint = nil var optvar*: ptr clong = nil proc open_math_library*(): bool = result = ## Open library. if math_handle == nil: math_handle = loadLib "libm.so" if math_handle == nil: return false cbrt = cast[cbrt.type](symAddr(math_handle, "cbrt")) if cbrt == nil: return false sqrt = cast[sqrt.type](symAddr(math_handle, "sqrt")) sqrt2 = cast[sqrt2.type](symAddr(math_handle, "sqrtf")) if sqrt2 == nil: return false reqvar = cast[reqvar.type](symAddr(math_handle, "reqvar")) if reqvar == nil: return false optvar = cast[optvar.type](symAddr(math_handle, "optvar")) true proc close_math_library*() = ## Close library. if math_handle != nil: cbrt = nil sqrt = nil sqrt2 = nil reqvar = nil optvar = nil math_handle.unloadLib math_handle = nil proc last_math_error*(): string = ## Returns the most recent error that occured from a call to open proc. #[ code follows… ]#
Macros
macro dlgencalls(name: static string; libpaths: static openArray[string]; body: untyped): untyped {....raises: [].}
-
Create open_name_library(): bool, close_name_library(), last_name_error(): string and C procedures/variables declared in body.
Function open_name_library() tries to load shared libary defined in libpaths and loads all symbols defined in body. This function returns true on success or false on error (no library found, symbol not found). Functions and variables marked with unchecked pragam are set to nil. Subsequent calls are ignored.
close_name_library() proc unloads the shared library. All symbols loaded are set to nil. Subsequent calls are ignored.
last_name_error() proc returns a human-readable string describing the most recent error that occured from a call to open_name_library() or empty string on no error.
The returned string does not include a trailing newline.
Templates
template dlgencalls(name: static string; libpath: static string; body: untyped): untyped
-
Create open_name_library(): bool, close_name_library(), last_name_error(): string and C procedures/variables declared in body.
Accepts single library path.
See dlgencalls for details.
template unchecked() {.pragma.}
- Functions and variables marked with this pragma do not cause open proc to fail and are set to nil if not found in shared library.