erlang rebar escriptize & nifs

寵の児 提交于 2019-12-05 02:31:12
rvirding

The problem is that the erlang:load_nif/1 function does not 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.

So if you call erlang:load_nif("jiffy.so") then 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).

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".

It does not seem possible to load a nif from an escript because erlang:load_nif does not look into archives. This is because most operating systems require a physical copy of the *.so that can be mapped to memory.

The best way to overcome this is by copying the *.so files into the output directory of the escript.

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

Take a look at the escript builder for edis. You will see this is how they load the eleveldb's nif for execution from an escript.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!