Nativ implementierte Funktionen in Erlang
Ein interessantes, neues Feature in Erlang sind die NIFs (native implemented functions). Diese Funktionen werden auf die gleiche Art und Weise angewandt wie die reinen Erlang-Funktionen. NIFs ermöglichen, unter anderem, ein über bestimmte Vorgaben abgesichertes Zugreifen auf externen Code. Jedes NIF-Modul muss bestimmte Callbacks implementieren, damit ein ordentliches Verwalten derselben möglich ist. Die Callbacks sind: load, reload, upgrade und unload.
Jeder dieser Funktionen erwarter ein ErlNifEnv* Argument sowie einen void-Pointer auf Modul-spezifische Daten. Und bis auf unload hat jeder Callback noch ein load-Argument vom Typ ERL_NIF_TERM.
Gegeben ist ein Modul namens funcModule.c
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
return 0;
}
[...andere Funktionen haben dieselbe Signatur...]
Bei unload schaut es aber etwas anders aus:
static void unload(ErlNifEnv* env, void* priv)
{
return;
}
funcModule.c erhält auch die eigens geschriebene Funktion an und fügt sie in eine Struktur vom Typ ErlNifFunc ein.
static ERL_NIF_TERM func1(ErlNifEnv* env, ERL_NIF_TERM arg)
{
[... eigener Code ... ]
}
static ErlNifFunc exported_funcs[] =
{
{"func1", 1, func1}
};
Der Aufbau der Sturuktur ist folgenermaßen: Erlang-Funktionsname, Arity (d.h. die Stelligkeit der Funktion, d.h. wiederum: wieviele Parameter erwartet sie) und der C-Name der Funktion)
Diese Struktur wird über das folgende Makro “bekannt gemacht”:
ERL_NIF_INIT(funcModule, exported_funcs, load, reload, upgrade, unload)
Das Modul wird jetzt kompiliert und anschließend vom Erlang-Code aus angewandt:
-module(func_consumer).
-export([start/0,func1/1]).
start() ->
erlang:load_nif("funcModule",0).
func1(_Value) ->
nif_error(?LINE).
nif_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
Der Aufbau ist denkbar einfach: zuerst wird das externe C-Modul mittels der Funktion “start” geladen. Danach versucht die exportierte func1 ausgeführt zu werden. Wenn mit dem C-Modul alles ordentlich verlaufen ist, wird die zuvor in C definierte Funktion ausgeführt, ansonsten gibt es einen Erlang-Fehler inklusive der Angaben, wo dieser passierte und in welchem Modul.
Somit ist die Ausführung ausfallsicher, denn im Falle eines Problems auf der C-Seite gibt es immer zumindest eine lesbare Erlang-Fehlermeldung.
Mehr Details zu diesem nützlichen Erlang-Feature gibt es hier zu lesen (die Beispiel-Codes in diesem Beitrag basieren auf diesem Tutorial): http://www.davispj.com/2009/11/23/erlang-nif-test.html
Technische Details zu NIFs gibt es hier: http://www.erlang.org/doc/man/erl_nif.html



