1
<?xml version="1.0" encoding="latin1" ?>
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
7
<year>2000</year><year>2011</year>
8
<holder>Ericsson AB. All Rights Reserved.</holder>
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/.
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
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>
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
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
66
<codeinclude file="complex6.erl" tag="" type="none"></codeinclude>
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>
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>
93
<codeinclude file="complex6_nif.c" tag="" type="none"></codeinclude>
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>
111
<title>Running the Example</title>
112
<p>1. Compile the C code.</p>
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>
119
Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
121
Eshell V5.7.5 (abort with ^G)
122
1> <input>c(complex6).</input>
124
<p>3. Run the example.</p>
126
3> <input>complex6:foo(3).</input>
128
4> <input>complex6:bar(5).</input>
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")