macos - Elixir NIF: ejemplo de Hello World en x64 Mac OSX
erlang native (1)
Hola, estoy tratando de obtener el ejemplo de Hello World para Erlang NIF ( Native Implemented Function ) que se muestra aquí http://www.erlang.org/doc/man/erl_nif.html para trabajar desde Elixir en OSX 64 bits.
Primero creo el código C:
/* 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)
Luego lo compilo con éxito utilizando gcc
para la arquitectura de 64 bits como se sugiere aquí 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
que produce el archivo necesario niftest.so
que debería poder hacer interfaz desde Erlang / Elixir. Mi Elixir (niftest.ex) se ve así (inspirado en un ejemplo más complejo que se informa aquí ):
defmodule Niftest do
@onload :init
def init() do
:erlang.load_nif("./niftest", 0)
:ok
end
def hello() do
"NIF library not loaded"
end
end
Ahora con niftest.so y niftest.ex en el mismo directorio iex
elixir usando iex
y iex
Niftest.hello
y todo lo que obtengo es: "Biblioteca NIF no cargada"
¿Me estoy perdiendo un paso vital? - ¡por favor ayuda!
La carga de la biblioteca está fallando silenciosamente. Puedes afirmar que tiene éxito usando:
:ok = :erlang.load_nif("./niftest", 0)
Esto resulta en un error:
** (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
Eso sucede porque una lib de NIF solo se puede invocar desde su módulo "propietario". El nombre de ese módulo es el primer argumento de la macro ERL_NIF_INIT
, por lo que puede solucionarlo cambiando esa llamada y volviendo a compilar:
ERL_NIF_INIT(Elixir.Niftest,nif_funcs,NULL,NULL,NULL,NULL)
También hay un error tipográfico en el gancho de carga. Debería ser:
@on_load :init