Erlang, возможно ли перезагрузить или обновить nif библиотеку без перезапуска оболочки?

У меня есть библиотека nif, и каждый раз, когда я перекомпилирую ее, я должен перезапускать оболочку, чтобы перезагрузить или обновить эту библиотеку.

Вот мой код Erlang:

-module(q4).
-export([init/0]).

-on_load(init/0).


init() ->
    erlang:load_nif("./q4_nif", reload).

Каждый раз, когда я компилирую модуль erlang, эта ошибка происходит:

`The on_load function for module q4 returned {error,
                                         {upgrade,
                                          "Upgrade not supported by this NIF library."}}`

и когда я звоню init/0 функция, эта ошибка возникает:{error,{reload,"Reload not supported by this NIF library."}}

Есть ли способ исправить эту проблему и загрузить новую библиотеку nif без перезапуска оболочки?

3 ответа

Решение

Как указано в сообщении об ошибке, вам необходимо предоставить upgrade функция в вашем NIF, который вы указываете в своем звонке ERL_NIF_INIT:

ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)

Функция обновления описана в erl_nif справочная страница.

ОБНОВЛЕНИЕ Причина найдена

Кажется delete должен вызываться дважды перед горячей перезагрузкой NIF. Это похоже на ошибку Erlang.

force_upgrade_module(Mod) ->
  true == code:purge(Mod),
  true == code:delete(Mod),
  code:purge(Mod),
  code:delete(Mod),
  {module,Mod} == code:load(Mod).

Даже с внедрением upgrade в ERL_NIF_INIT Есть еще некоторые проблемы, которые могут зависеть от платформы. Например, в macOS: не стесняйтесь удалять priv/{{module}}.so после звонка load_nif в модуле заглушки erlang, и он просто продолжит молча, преуспеет и не перезагрузит NIF .so.

@steve-vinoski что должно load, reload, upgrade а также unload для этого случая?

      ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)
Другие вопросы по тегам