2015-04-27 8 views
8

Hallo Ich versuche, die Hallo Welt Beispiel für Erlang NIF (Mutter implementierte Funktion) hier gezeigt zu bekommen http://www.erlang.org/doc/man/erl_nif.html von Elixir auf OSX 64-Bit zu arbeiten.Elixir NIF- Hallo Welt Beispiel auf x64 Mac OSX

Zunächst erstelle ich den C-Code:

/* niftest.c */ 
#include "erl_nif.h" 

static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) 
{ 
    return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1); 
} 

static ErlNifFunc nif_funcs[] = 
{ 
    {"hello", 0, hello} 
}; 

ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL) 

Dann, als ich es erfolgreich kompilieren gcc für 64-Bit-Architektur hier vorgeschlagen Erlang NIF Test -- OS X Lion

gcc -undefined dynamic_lookup -dynamiclib niftest.c -o niftest.so -I /usr/local/Cellar/erlang/R14B02/lib/erlang/usr/include 

, die die notwendige Datei erzeugt niftest.so, dass ich sollte in der Lage sein, von Erlang/Elixir zu interagieren. Mein Elixir (niftest.ex) sieht wie folgt aus (inspiriert von einem komplexeren Beispiel berichtet here):

defmodule Niftest do 
@onload :init 
    def init() do 
    :erlang.load_nif("./niftest", 0) 
    :ok 
    end 

    def hello() do 
    "NIF library not loaded" 
    end 

end 

Jetzt mit niftest.so und niftest.ex im selben Verzeichnis I Feuer Elixier iex mit und geben Sie in Niftest.hello und alles, was ich zurück bekomme, ist: "NIF-Bibliothek nicht geladen"

Fehle ich einen entscheidenden Schritt? - bitte helfen!

Antwort

11

Die Auslastung der Bibliothek schlägt im Hintergrund fehl. Sie können behaupten, dass es gelingt mit:

:ok = :erlang.load_nif("./niftest", 0) 

Dies zu einem Fehler führt:

** (MatchError) no match of right hand side value: 
{:error, {:bad_lib, 'Library module name \'niftest\' does not match calling module \'\'Elixir.Niftest\'\''}} 
niftest.ex:4: Niftest.init/0 

das, weil ein NIF lib nur von seinem „Besitz“ Modul aufgerufen werden kann passiert. Der Name dieses Moduls ist das erste Argument der ERL_NIF_INIT Makro, so können Sie dies beheben, indem diesen Anruf zu ändern und neu zu kompilieren:

ERL_NIF_INIT(Elixir.Niftest,nif_funcs,NULL,NULL,NULL,NULL) 

Es gibt auch einen Tippfehler in der Lasthaken. Es sollte sein:

@on_load :init 
+0

Sie haben Recht - Ihr wird die angenommene Antwort sein - vielen Dank! – GavinBrelstaff

+0

Es stellt sich heraus, dass die @onload: init-Direktive auch nicht wie erwartet funktioniert - also muss ich zuerst Niftest.init aufrufen, bevor ich Nifteast.hello aufruft. Nicht sicher warum. – GavinBrelstaff

+3

'@ onload' funktioniert nicht, weil es' @ on_load' sein sollte. Die Antwort wurde aktualisiert –