Erlang Rebar Escriptize & NIFS



如果我自己写脚本,我可以使用nif,但是当我使用钢筋描述时,无法找到nif函数。我认为这是因为*。所以对象不会像光束文件那样打包。下面是一个简单的例子;

rebar.config:

{deps, [
   {'jiffy', "", {git, "https://github.com/davisp/jiffy.git", {branch, master}}}
]}.
{escript_incl_apps, [jiffy]}.
%% I tried this to see what happens if the so got in there but didn't help
{escript_incl_extra, [{"deps/jiffy/priv/jiffy.so", "/path/to/my/proj"}]}.

test.erl:

-module(test).
-export([main/1]).
main(_Args) ->
    jiffy:decode(<<"1">>),
    ok.

钢筋get-deps编译说明
/测试。

,结果是

escript: exception error: undefined function jiffy:decode/1
  in function  test:main/1 (src/test.erl, line 7)
  in call from escript:run/2 (escript.erl, line 741)
  in call from escript:start/1 (escript.erl, line 277)
  in call from init:start_it/1
  in call from init:start_em/1

有办法克服这个吗?

问题是erlang:load_nif/1函数不隐式地使用任何搜索路径也不在试图找到.so文件时做任何聪明的事情。它只是尝试按照文件名参数所给出的方式加载文件。如果它不是一个绝对文件名,那么它将尝试加载相对于当前工作目录的文件。完全按照你的要求加载

所以如果你调用erlang:load_nif("jiffy.so"),那么它将尝试从当前工作目录加载"jiffy.so"。我使用的一个简单的工作是这样做,它使用NIF_DIR环境变量:

load_nifs() ->
    case os:getenv("NIF_DIR") of
        false -> Path = ".";
        Path -> Path
    end,
    ok = erlang:load_nif(Path ++ "/gpio_nifs", 0).

可以很容易地扩展为沿着搜索路径循环查找文件。请注意,NIF_DIR不是一个特殊的名称,只是我"发明"的名称。

似乎不可能从脚本加载nif,因为erlang:load_nif不查看存档。这是因为大多数操作系统都需要一个可以映射到内存的*.so的物理副本。

解决这个问题的最好方法是复制*。将文件放入脚本的输出目录中。

  {ok, _Bytes} = file:copy("deps/jiffy/priv/jiffy.so", "bin/jiffy.so"),

看看edis的脚本构建器。您将看到他们是如何从脚本加载eleveldb的nif以执行的。

相关内容

  • 没有找到相关文章

最新更新