9

嗨,我正在尝试获取此处 http://www.erlang.org/doc/man/erl_nif.html显示的 Erlang NIF(本机实现功能)的Hello World示例,以便 在 OSX 64 位上从 Elixir 工作。

首先,我创建 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)

然后我按照这里建议的Erlang NIF Test -- OS X Liongcc成功地使用64 位架构 编译它

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

它产生了niftest.so我应该能够从 Erlang/Elixir 接口到的必要文件。我的 Elixir (niftest.ex) 看起来像这样(受此处报告的更复杂示例的启发):

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

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

end

现在在同一个目录中使用 niftest.so 和 niftest.ex 我启动 elixiriex并输入,Niftest.hello我得到的只是:“NIF 库未加载”

我错过了重要的一步吗?- 请帮忙!

4

1 回答 1

11

库的加载正在静默失败。您可以使用以下方法断言它成功:

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

这会导致错误:

** (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

发生这种情况是因为只能从其“拥有”模块调用 NIF 库。该模块的名称是ERL_NIF_INIT宏的第一个参数,因此您可以通过更改该调用并重新编译来解决此问题:

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

负载钩中也有一个错字。它应该是:

@on_load :init
于 2015-04-27T10:16:12.413 回答