mirror of
https://github.com/nim-lang/Nim.git
synced 2026-03-01 22:28:29 +00:00
Mentions memory management.
This commit is contained in:
@@ -265,7 +265,8 @@ Create a ``maths.c`` file with the following content:
|
||||
}
|
||||
|
||||
Now you can run the following Unix like commands to first generate C sources
|
||||
form the Nimrod code, then link it into a static binary::
|
||||
form the Nimrod code, then link them into a static binary along your main C
|
||||
program::
|
||||
|
||||
$ nimrod c --noMain --noLinking --header:fib.h fib.nim
|
||||
$ gcc -o m -Inimcache -Ipath/to/nimrod/lib nimcache/*.c maths.c
|
||||
@@ -318,17 +319,72 @@ from the previous section):
|
||||
|
||||
Compile the Nimrod code to JavaScript with ``nimrod js -o:fib.js fib.nim`` and
|
||||
open ``mhost.html`` in a browser. If the browser supports javascript, you
|
||||
should see an alert box displaying the text ``Fib for 9 is 34``.
|
||||
should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned
|
||||
earlier, JavaScript doesn't require an initialisation call to ``NimMain`` or
|
||||
similar function and you can call the exported Nimrod proc directly.
|
||||
|
||||
|
||||
Memory management
|
||||
=================
|
||||
|
||||
In the previous sections the ``NimMain()`` function reared its head. Since
|
||||
JavaScript already provides automatic memory management, you can freely pass
|
||||
objects between the two language without problems. In C and derivate languages
|
||||
you need to be careful about what you do and how you share memory. The
|
||||
previous examples only dealt with simple scalar values, but passing a Nimrod
|
||||
string to C, or reading back a C string in Nimrod already requires you to be
|
||||
aware of who controls what to avoid crashing.
|
||||
|
||||
|
||||
Strings and C strings
|
||||
---------------------
|
||||
|
||||
Garbage collection, life of objects
|
||||
-----------------------------------
|
||||
The manual mentions that `Nimrod strings are implicitly convertible to
|
||||
cstrings <manual.html#cstring-type>`_ which makes interaction usually
|
||||
painless. Most C functions accepting a Nimrod string converted to a
|
||||
``cstring`` will likely not need to keep this string around and by the time
|
||||
they return the string won't be needed any more. However, for the rare cases
|
||||
where a Nimrod string has to be preserved and made available to the C backend
|
||||
as a ``cstring``, you will need to manually prevent the string data from being
|
||||
freed with `GC_ref <system.html#GC_ref>`_ and `GC_unref
|
||||
<system.html#GC_unref>`_.
|
||||
|
||||
A similar thing happens with C code invoking Nimrod code which returns a
|
||||
``cstring``. Consider the following proc:
|
||||
|
||||
.. code-block:: nimrod
|
||||
|
||||
proc gimme(): cstring {.exportc.} =
|
||||
result = "Hey there C code! " & $random(100)
|
||||
|
||||
Since Nimrod's garbage collector is not aware of the C code, once the
|
||||
``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
|
||||
However, from a practical standpoint, the C code invoking the ``gimme``
|
||||
function directly will be able to use it since Nimrod's garbage collector has
|
||||
not had a chance to run *yet*. This gives you enough time to make a copy for
|
||||
the C side of the program, as calling any further Nimrod procs *might* trigger
|
||||
garbage collection making the previously returned string garbage. Or maybe you
|
||||
are `triggering yourself the collection <gc.html>`_.
|
||||
|
||||
|
||||
Custom data types
|
||||
-----------------
|
||||
|
||||
Just like strings, custom data types that are to be shared between Nimrod and
|
||||
the backend will need careful consideration of who controlls who. If you want
|
||||
to hand a Nimrod reference to C code, you will need to use `GC_ref
|
||||
<system.html#GC_ref>`_ to mark the reference as used, so it does not get
|
||||
freed. And for the C backend you will need to expose the `GC_unref
|
||||
<system.html#GC_unref>`_ proc to clean up this memory when it is not required
|
||||
any more.
|
||||
|
||||
Again, if you are wrapping a library which *mallocs* and *frees* data
|
||||
structures, you need to expose the appropriate *free* function to Nimrod so
|
||||
you can clean it up. And of course, once cleaned you should avoid accessing it
|
||||
from Nimrod (or C for that matter). Typically C data structures have their own
|
||||
``malloc_structure`` and ``free_structure`` specific functions, so wrapping
|
||||
these for the Nimrod side should be enough.
|
||||
|
||||
|
||||
Thread coordination
|
||||
-------------------
|
||||
===================
|
||||
|
||||
Reference in New Issue
Block a user