Erlang,是否可以在不重新启动shell的情况下重新加载或升级nif库?

时间:2015-10-30 00:15:44

标签: c erlang erlang-nif

我有一个nif库,每次我重新编译它,我都必须重新启动shell来重新加载或升级这个库。

这是我的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库而不重新启动shell?

2 个答案:

答案 0 :(得分:4)

如错误消息所示,您需要在NIF中提供upgrade功能,您在致电ERL_NIF_INIT时指定该功能:

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

升级功能记录在erl_nif man page

答案 1 :(得分:1)

更新找到根本原因

在热重新加载NIF之前,delete必须调用两次这似乎是一个错误的错误。

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上:在erlang存根模块中调用priv/{{module}}.so之后随意删除load_nif,它将继续静默成功,而不是真正重新加载NIF .so。