Erlang,是否可以在不重新启动 shell 的情况下重新加载或升级 nif 库?
Erlang, Is it possible to reload or upgrade a nif library without restart the shell?
我有一个 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."}}
有没有办法解决这个问题并在不重新启动 shell 的情况下加载新的 nif 库?
如错误消息所示,您需要在您的 NIF 中提供一个 upgrade
函数,您在调用 ERL_NIF_INIT
:
时指定该函数
ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)
升级功能记录在erl_nif
man page。
更新 找到根本原因
看来 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).
即使在 ERL_NIF_INIT
中实施了 upgrade
,仍然存在一些问题,这些问题可能是也可能不是特定于平台的。例如,在 macOS 上:在 erlang 存根模块中调用 load_nif
后随意删除 priv/{{module}}.so
,它将继续默默地成功,而不是真正重新加载 NIF .so。
@史蒂夫维诺斯基
对于这种情况,load
、reload
、upgrade
和 unload
应该是什么?
ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)
我有一个 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."}}
有没有办法解决这个问题并在不重新启动 shell 的情况下加载新的 nif 库?
如错误消息所示,您需要在您的 NIF 中提供一个 upgrade
函数,您在调用 ERL_NIF_INIT
:
ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)
升级功能记录在erl_nif
man page。
更新 找到根本原因
看来 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).
即使在 ERL_NIF_INIT
中实施了 upgrade
,仍然存在一些问题,这些问题可能是也可能不是特定于平台的。例如,在 macOS 上:在 erlang 存根模块中调用 load_nif
后随意删除 priv/{{module}}.so
,它将继续默默地成功,而不是真正重新加载 NIF .so。
@史蒂夫维诺斯基
对于这种情况,load
、reload
、upgrade
和 unload
应该是什么?
ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)