gpt4 book ai didi

Erlang Rebar escriptize 和 nifs

转载 作者:行者123 更新时间:2023-12-01 20:22:26 25 4
gpt4 key购买 nike

如果我自己编写 escript,我可以使用 nif,但是当我使用 rebar escriptize 时,找不到 nif 函数。我认为这是因为 *.so 对象没有像 Beam 文件那样被打包。这是一个简单的例子;

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 编译 escriptize
./测试

结果是

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 并不是一个特殊的名称,只是我“发明”的一个名称。

关于Erlang Rebar escriptize 和 nifs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15617798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com