This section outlines an example of how to solve the example
problem in
NIFs were introduced in Erlang/OTP R13B03 as an experimental
feature. It is a simpler and more efficient way of calling C-code
than using port drivers. NIFs are most suitable for synchronous
functions, such as
A NIF is a function that is implemented in C instead of Erlang. NIFs appear as any other functions to the callers. They belong to a module and are called like any other Erlang functions. The NIFs of a module are compiled and linked into a dynamic loadable, shared library (SO in UNIX, DLL in Windows). The NIF library must be loaded in runtime by the Erlang code of the module.
As a NIF library is dynamically linked into the emulator process, this is the fastest way of calling C-code from Erlang (alongside port drivers). Calling NIFs requires no context switches. But it is also the least safe, because a crash in a NIF brings the emulator down too.
Even if all functions of a module are NIFs, an Erlang module is still needed for two reasons:
Normally these are minimal stub implementations that throw an exception. But they can also be used as fallback implementations for functions that do not have native implemenations on some architectures.
NIF libraries are loaded by calling
Here, the directive
Loading the NIF library overrides the stub implementations
and cause calls to
The NIFs of the module are compiled and linked into a
shared library. Each NIF is implemented as a normal C function. The macro
The function arguments passed to a NIF appears in an array
Here,
The first argument must be the name of the Erlang module as a C-identifier. It will be stringified by the macro.
Function arguments and return values are represented as values
of type
Step 1. Compile the C code:
unix> gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c windows> cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c
Step 2: Start Erlang and compile the Erlang code:
> erl Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] Eshell V5.7.5 (abort with ^G) 1> c(complex6). {ok,complex6}
Step 3: Run the example:
3> complex6:foo(3). 4 4> complex6:bar(5). 10 5> complex6:foo("not an integer"). ** exception error: bad argument in function complex6:foo/1 called as comlpex6:foo("not an integer")