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

lpwwtiir  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(204)

我有一个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库?

qnyhuwrf

qnyhuwrf1#

如错误消息所示,您需要在NIF中提供一个upgrade函数,该函数在对ERL_NIF_INIT的调用中指定:

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

升级功能记录在erl_nif man page中。

0h4hbjxa

0h4hbjxa2#

UPDATE找到根本原因

**似乎在热重新加载NIF之前必须调用 * 两次 * delete。**这似乎是一个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,仍然存在一些问题,这些问题可能是特定于平台的,也可能不是特定于平台的。在Erlang存根模块中调用load_nif之后,您可以随意删除priv/{{module}}.so,它将继续执行,而不会真正重新加载NIF.so。

相关问题