~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to system/doc/tutorial/nif.xmlsrc

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="latin1" ?>
 
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
 
3
 
 
4
<chapter>
 
5
  <header>
 
6
    <copyright>
 
7
      <year>2000</year><year>2011</year>
 
8
      <holder>Ericsson AB. All Rights Reserved.</holder>
 
9
    </copyright>
 
10
    <legalnotice>
 
11
      The contents of this file are subject to the Erlang Public License,
 
12
      Version 1.1, (the "License"); you may not use this file except in
 
13
      compliance with the License. You should have received a copy of the
 
14
      Erlang Public License along with this software. If not, it can be
 
15
      retrieved online at http://www.erlang.org/.
 
16
    
 
17
      Software distributed under the License is distributed on an "AS IS"
 
18
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
19
      the License for the specific language governing rights and limitations
 
20
      under the License.
 
21
    
 
22
    </legalnotice>
 
23
 
 
24
    <title>NIFs</title>
 
25
    <prepared></prepared>
 
26
    <docno></docno>
 
27
    <date></date>
 
28
    <rev></rev>
 
29
    <file>nif.xml</file>
 
30
  </header>
 
31
  <p>This is an example of how to solve the <seealso marker="example">example problem</seealso>
 
32
     by using NIFs. NIFs where introduced in R13B03 as an experimental
 
33
     feature. It is a simpler and more efficient way of calling C-code
 
34
     than using port drivers. NIFs are most suitable for synchronous functions like
 
35
     <c>foo</c> and <c>bar</c> in the example, that does some
 
36
     relatively short calculations without side effects and return the result.</p>
 
37
  <section>
 
38
    <title>NIFs</title>
 
39
    <p>A NIF (Native Implemented Function) is a function that is
 
40
      implemented in C instead of Erlang. NIFs appear as any other functions to
 
41
      the callers. They belong to a module and are called like any other Erlang
 
42
      functions. The NIFs of a module are compiled and linked into a dynamic
 
43
      loadable shared library (SO in Unix, DLL in Windows). The NIF library must
 
44
      be loaded in runtime by the Erlang code of the module.</p>
 
45
    <p>Since a NIF library is dynamically linked into the emulator
 
46
      process, this is the fastest way of calling C-code from Erlang (alongside
 
47
      port drivers). Calling NIFs requires no context switches. But it is also
 
48
      the least safe, because a crash in a NIF will bring the emulator down
 
49
      too.</p>
 
50
  </section>
 
51
 
 
52
  <section>
 
53
    <title>Erlang Program</title>
 
54
    <p>Even if all functions of a module will be NIFs, you still need an Erlang
 
55
      module for two reasons. First, the NIF library must be explicitly loaded
 
56
      by Erlang code in the same module. Second, all NIFs of a module must have
 
57
      an Erlang implementation as well. Normally these are minimal stub
 
58
      implementations that throw an exception. But it can also be used as
 
59
      fallback implementations for functions that do not have native
 
60
      implemenations on some architectures.</p>
 
61
    <p>NIF libraries are loaded by calling <c>erlang:load_nif/2</c>, with the
 
62
      name of the shared library as argument. The second argument can be any
 
63
      term that will be passed on to the library and used for
 
64
      initialization.</p>
 
65
 
 
66
    <codeinclude file="complex6.erl" tag="" type="none"></codeinclude>
 
67
 
 
68
    <p>We use the directive <c>on_load</c> to get function <c>init</c> to be
 
69
      automatically called when the module is loaded. If <c>init</c>
 
70
      returns anything other than <c>ok</c>, such when the loading of
 
71
      the NIF library fails in this example, the module will be
 
72
      unloaded and calls to functions within it will fail.</p>
 
73
    <p>Loading the NIF library will override the stub implementations
 
74
      and cause calls to <c>foo</c> and <c>bar</c> to be dispatched to
 
75
      the NIF implementations instead.</p>
 
76
  </section>
 
77
  <section>
 
78
    <title>NIF library code</title>
 
79
    <p>The NIFs of the module are compiled and linked into a
 
80
      shared library. Each NIF is implemented as a normal C function. The macro
 
81
      <c>ERL_NIF_INIT</c> together with an array of structures defines the names,
 
82
      arity and function pointers of all the NIFs in the module. The header
 
83
      file <c>erl_nif.h</c> must be included. Since the library is a shared
 
84
      module, not a program, no main function should be present.</p>
 
85
    <p>The function arguments passed to a NIF appears in an array <c>argv</c>,
 
86
      with <c>argc</c> as the length of the array and thus the arity of the
 
87
      function. The Nth argument of the function can be accessed as
 
88
      <c>argv[N-1]</c>. NIFs also takes an environment argument that
 
89
      serves as an opaque handle that is needed to be passed on to
 
90
      most API functions. The environment contains information about
 
91
      the calling Erlang process.</p>
 
92
 
 
93
    <codeinclude file="complex6_nif.c" tag="" type="none"></codeinclude>
 
94
 
 
95
    <p>The first argument to <c>ERL_NIF_INIT</c> must be the name of the
 
96
      Erlang module as a C-identifier. It will be stringified by the
 
97
      macro. The second argument is the array of <c>ErlNifFunc</c>
 
98
      structures containing name, arity and function pointer of
 
99
      each NIF. The other arguments are pointers to callback functions
 
100
      that can be used to initialize the library. We do not use them
 
101
      is this simple example so we set them all to <c>NULL</c>.</p>
 
102
    <p>Function arguments and return values are represented as values
 
103
      of type <c>ERL_NIF_TERM</c>. We use functions like <c>enif_get_int</c> 
 
104
      and <c>enif_make_int</c> to convert between Erlang term and C-type. 
 
105
      If the function argument <c>argv[0]</c> is not an integer then
 
106
      <c>enif_get_int</c> will return false, in which case we return
 
107
      by throwing a <c>badarg</c>-exception with <c>enif_make_badarg</c>.</p>
 
108
  </section>
 
109
 
 
110
  <section>
 
111
    <title>Running the Example</title>
 
112
    <p>1. Compile the C code.</p>
 
113
    <pre>
 
114
unix> <input>gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c</input>
 
115
windows> <input>cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c</input></pre>
 
116
    <p>2. Start Erlang and compile the Erlang code.</p>
 
117
    <pre>
 
118
> <input>erl</input>
 
119
Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
 
120
 
 
121
Eshell V5.7.5  (abort with ^G)
 
122
1> <input>c(complex6).</input>
 
123
{ok,complex6}</pre>
 
124
    <p>3. Run the example.</p>
 
125
<pre>
 
126
3> <input>complex6:foo(3).</input>
 
127
4
 
128
4> <input>complex6:bar(5).</input>
 
129
10
 
130
5> <input>complex6:foo("not an integer").</input>
 
131
** exception error: bad argument
 
132
     in function  complex6:foo/1
 
133
        called as comlpex6:foo("not an integer")
 
134
</pre>
 
135
</section>
 
136
</chapter>