123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- Foreign function interface
- ==========================
- Nim's `FFI`:idx: (foreign function interface) is extensive and only the
- parts that scale to other future backends (like the LLVM/JavaScript backends)
- are documented here.
- Importc pragma
- --------------
- The ``importc`` pragma provides a means to import a proc or a variable
- from C. The optional argument is a string containing the C identifier. If
- the argument is missing, the C name is the Nim identifier *exactly as
- spelled*:
- .. code-block::
- proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
- Note that this pragma is somewhat of a misnomer: Other backends do provide
- the same feature under the same name. Also, if one is interfacing with C++
- the `ImportCpp pragma <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
- interfacing with Objective-C the `ImportObjC pragma
- <manual.html#implementation-specific-pragmas-importobjc-pragma>`_ can be used.
- The string literal passed to ``importc`` can be a format string:
- .. code-block:: Nim
- proc p(s: cstring) {.importc: "prefix$1".}
- In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
- is available and a literal dollar sign must be written as ``$$``.
- Exportc pragma
- --------------
- The ``exportc`` pragma provides a means to export a type, a variable, or a
- procedure to C. Enums and constants can't be exported. The optional argument
- is a string containing the C identifier. If the argument is missing, the C
- name is the Nim identifier *exactly as spelled*:
- .. code-block:: Nim
- proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
- Note that this pragma is somewhat of a misnomer: Other backends do provide
- the same feature under the same name.
- The string literal passed to ``exportc`` can be a format string:
- .. code-block:: Nim
- proc p(s: string) {.exportc: "prefix$1".} =
- echo s
- In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
- is available and a literal dollar sign must be written as ``$$``.
- Extern pragma
- -------------
- Like ``exportc`` or ``importc``, the ``extern`` pragma affects name
- mangling. The string literal passed to ``extern`` can be a format string:
- .. code-block:: Nim
- proc p(s: string) {.extern: "prefix$1".} =
- echo s
- In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
- is available and a literal dollar sign must be written as ``$$``.
- Bycopy pragma
- -------------
- The ``bycopy`` pragma can be applied to an object or tuple type and
- instructs the compiler to pass the type by value to procs:
- .. code-block:: nim
- type
- Vector {.bycopy, pure.} = object
- x, y, z: float
- Byref pragma
- ------------
- The ``byref`` pragma can be applied to an object or tuple type and instructs
- the compiler to pass the type by reference (hidden pointer) to procs.
- Varargs pragma
- --------------
- The ``varargs`` pragma can be applied to procedures only (and procedure
- types). It tells Nim that the proc can take a variable number of parameters
- after the last specified parameter. Nim string values will be converted to C
- strings automatically:
- .. code-block:: Nim
- proc printf(formatstr: cstring) {.nodecl, varargs.}
- printf("hallo %s", "world") # "world" will be passed as C string
- Union pragma
- ------------
- The ``union`` pragma can be applied to any ``object`` type. It means all
- of the object's fields are overlaid in memory. This produces a ``union``
- instead of a ``struct`` in the generated C/C++ code. The object declaration
- then must not use inheritance or any GC'ed memory but this is currently not
- checked.
- **Future directions**: GC'ed memory should be allowed in unions and the GC
- should scan unions conservatively.
- Packed pragma
- -------------
- The ``packed`` pragma can be applied to any ``object`` type. It ensures
- that the fields of an object are packed back-to-back in memory. It is useful
- to store packets or messages from/to network or hardware drivers, and for
- interoperability with C. Combining packed pragma with inheritance is not
- defined, and it should not be used with GC'ed memory (ref's).
- **Future directions**: Using GC'ed memory in packed pragma will result in
- compile-time error. Usage with inheritance should be defined and documented.
- Unchecked pragma
- ----------------
- The ``unchecked`` pragma can be used to mark a named array as ``unchecked``
- meaning its bounds are not checked. This is often useful to
- implement customized flexibly sized arrays. Additionally an unchecked array is
- translated into a C array of undetermined size:
- .. code-block:: nim
- type
- ArrayPart{.unchecked.} = array[0, int]
- MySeq = object
- len, cap: int
- data: ArrayPart
- Produces roughly this C code:
- .. code-block:: C
- typedef struct {
- NI len;
- NI cap;
- NI data[];
- } MySeq;
- The base type of the unchecked array may not contain any GC'ed memory but this
- is currently not checked.
- **Future directions**: GC'ed memory should be allowed in unchecked arrays and
- there should be an explicit annotation of how the GC is to determine the
- runtime size of the array.
- Dynlib pragma for import
- ------------------------
- With the ``dynlib`` pragma a procedure or a variable can be imported from
- a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX).
- The non-optional argument has to be the name of the dynamic library:
- .. code-block:: Nim
- proc gtk_image_new(): PGtkWidget
- {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
- In general, importing a dynamic library does not require any special linker
- options or linking with import libraries. This also implies that no *devel*
- packages need to be installed.
- The ``dynlib`` import mechanism supports a versioning scheme:
- .. code-block:: nim
- proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl,
- importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}
- At runtime the dynamic library is searched for (in this order)::
- libtcl.so.1
- libtcl.so.0
- libtcl8.5.so.1
- libtcl8.5.so.0
- libtcl8.4.so.1
- libtcl8.4.so.0
- libtcl8.3.so.1
- libtcl8.3.so.0
- The ``dynlib`` pragma supports not only constant strings as argument but also
- string expressions in general:
- .. code-block:: nim
- import os
- proc getDllName: string =
- result = "mylib.dll"
- if existsFile(result): return
- result = "mylib2.dll"
- if existsFile(result): return
- quit("could not load dynamic library")
- proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
- **Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
- strings, because they are precompiled.
- **Note**: Passing variables to the ``dynlib`` pragma will fail at runtime
- because of order of initialization problems.
- **Note**: A ``dynlib`` import can be overriden with
- the ``--dynlibOverride:name`` command line option. The Compiler User Guide
- contains further information.
- Dynlib pragma for export
- ------------------------
- With the ``dynlib`` pragma a procedure can also be exported to
- a dynamic library. The pragma then has no argument and has to be used in
- conjunction with the ``exportc`` pragma:
- .. code-block:: Nim
- proc exportme(): int {.cdecl, exportc, dynlib.}
- This is only useful if the program is compiled as a dynamic library via the
- ``--app:lib`` command line option. This pragma only has an effect for the code
- generation on the Windows target, so when this pragma is forgotten and the dynamic
- library is only tested on Mac and/or Linux, there won't be an error. On Windows
- this pragma adds ``__declspec(dllexport)`` to the function declaration.
|