我正在使用 NIF 将 C++ api 与 Elixir 集成。现在,每当我加载 NIF 时,我都想初始化一些变量/数据,这些变量/数据将在 NIF 调用中保持不变。我试图通过load
调用中提到的函数来实现相同的目标ERL_NIF_INIT
。但我观察到一些奇怪的行为超出了加载功能。请查看下面提到的示例,然后我将进一步解释该问题:
#include <erl_nif.h>
static ERL_NIF_TERM sample(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
return enif_make_atom(env, "ok");
}
static ErlNifFunc nif_funcs[] = {{"sample", 1, sample}};
static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
try {
1 / 0; // nif loads if this is the case
int x = 1 / 0; // float point exception segmentation fault when used this line
} catch (...) {
return 1;
}
return 0;
}
ERL_NIF_INIT(Elixir.Sample, nif_funcs, load, NULL, NULL, NULL);
现在仔细观察load
包含try/catch
块的函数,当我1 / 0;
在块的主体中使用表达式时try
,会加载 NIF,但是当表达式1 / 0;
被 erlang 替换时,即使我添加了块来处理异常int x = 1 / 0;
,vm 也无法加载 NIF 并崩溃。谁可以给我解释一下这个?我在这里真的需要帮助。floating point exception segmentation fault
try/catch
这是用于接口的长生不老药代码:
defmodule Sample do
@on_load :load_nifs
def load_nifs do
:ok =
:sample
|> :code.priv_dir()
|> Path.join("sample")
|> :erlang.load_nif("0.0.1")
end
def sample(_) do
raise "sample/1 Function not implemented"
end
end
用于编译 NIF 的命令g++ -fPIC -shared sample.cpp -o sample.so
PS - 感谢您花时间阅读本文,我真的很感激。