I am working on integrating a C++ api with Elixir, by using NIFs. Now whenever I load the NIF, I want to initialize some variables/data which will be persisted across NIF calls. I was trying to achieve the same by load
function mentioned in the ERL_NIF_INIT
call. But I am observing some weird behavior out of load function. Please have a look at the below mentioned example and then I’ll explain the issue further:
#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);
Now closely observe the load
function containing the try/catch
block, when I use 1 / 0;
expression in the body of try
block, NIF is loaded but when the expression 1 / 0;
is replaced by int x = 1 / 0;
erlang vm fails to load NIF and crashes with floating point exception segmentation fault
even if I have added the try/catch
block to handle the exception. Can someone explain this to me? I really need help here.
Here is the elixir code used for interfacing:
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
Command used to compile NIF g++ -fPIC -shared sample.cpp -o sample.so
P.S. - Thanks for your time to read this, I really appreciate it.