manual split up into multiple files; documented the new concurrency system
This commit is contained in:
parent
e9dec2feed
commit
2c1f3f75f5
31 changed files with 6198 additions and 5901 deletions
209
doc/manual/ffi.txt
Normal file
209
doc/manual/ffi.txt
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
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 will provide
|
||||
the same feature under the same name. Also, if one is interfacing with C++
|
||||
the `ImportCpp pragma <nimc.html#importcpp-pragma>`_ and
|
||||
interfacing with Objective-C the `ImportObjC pragma
|
||||
<nimc.html#importobjc-pragma>`_ can be used.
|
||||
|
||||
|
||||
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 will provide
|
||||
the same feature under the same name.
|
||||
|
||||
|
||||
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``.
|
||||
|
||||
|
||||
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
|
||||
TVector {.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 when one wishes to
|
||||
implement his own flexibly sized arrays. Additionally an unchecked array is
|
||||
translated into a C array of undetermined size:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
ArrayPart{.unchecked.} = array[0..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 bounds checking done at compile time is not disabled for now, so to access
|
||||
``s.data[C]`` (where ``C`` is a constant) the array's index needs needs to
|
||||
include ``C``.
|
||||
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue