埃尔朗钢筋NIFS [英] erlang rebar escriptize & nifs

查看:178
本文介绍了埃尔朗钢筋NIFS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用nif的,如果我自己写的escript,但是当我使用rebar escriptize nif功能无法找到。我认为这是因为* .so对象没有像束文件那样打包。这是一个简单的例子;

I can use nif's if I write the escript myself, however when I use rebar escriptize the nif functions cannot be found. I think it is because *.so objects are not getting packed like beam files. Here is an simple example;

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.

rebar get-deps compile escriptize

./test

rebar get-deps compile escriptize
./test

,结果是

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

有没有办法克服这个问题?

Is there a way to overcome this ?

推荐答案

问题是使用 erlang:load_nif / 1 功能使用隐式使用任何搜索路径也不做任何聪明的尝试找到 .so 文件。它只是尝试按文件名参数给出的字面加载文件。如果它不是一个绝对的文件名,那么它将尝试加载相对于当前工作目录的文件。

The problem is that the erlang:load_nif/1 function does not use implicitly use any search path nor do anything smart in trying to find the .so file. It just tries to load the file literally as given by the file name argument. If it is not an absolute file name then it will try to load the file relative to the current working directory. It loads exactly what you tell it to load.

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

So if you call erlang:load_nif("jiffy.so") the it will try to load ""jiffy.so" from your current working directory. A simple work around that I have used is to do something like this which uses the NIF_DIR environment variable:

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

请注意, NIF_DIR 不是一个特殊的名称,只有一个我已经发明了。

This can easily be extended to loop down a search path to find the file. Note that NIF_DIR is not a special name, just one I have "invented".

这篇关于埃尔朗钢筋NIFS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆