[erlang-questions] erl_nif: persist binary across calls

Harris, Robert robert.harris@REDACTED
Fri Feb 8 15:04:13 CET 2019


Hi,

I am writing a NIF library in which I would like to create persistent binary terms
in my load() callback.  The purpose of these terms is to act as ready-made keys
for frequent calls to enif_get_map_value() in successive calls to other NIFs in the
same library.

My test case is

> #include <string.h>
> #include <erl_nif.h>
> 
> ERL_NIF_TERM persistent;
> 
> static ERL_NIF_TERM
> create_binary(ErlNifEnv *env)
> {
>         ErlNifBinary binary;
>         char *data = "abcdefghijklmnopqrstuvwxyz";
>         size_t size = strlen(data);
> 
>         (void) enif_alloc_binary(size, &binary);
>         memcpy(binary.data, data, size);
>         binary.size = size;
>         return (enif_make_binary(env, &binary));
> }
> 
> int
> load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info)
> {
>         persistent = create_binary(env);
>         return (0);
> }
> 
> static ERL_NIF_TERM
> world_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>          return (persistent);
> }
> 
> static ERL_NIF_TERM
> hello_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>          return (create_binary(env));
> }
> 
> static ErlNifFunc nif_funcs[] = {
>         {"hello", 0, hello_nif},
>         {"world", 0, world_nif},
> };
> 
> ERL_NIF_INIT(hello, nif_funcs, &load, NULL, NULL, NULL)

An example of the behaviour I see is

> Erlang/OTP 20 [erts-9.3.3.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:10] [hipe] [kernel-poll:false]
> 
> Eshell V9.3.3.3  (abort with ^G)
> 1>
> 1> hello:hello().
> <<"abcdefghijklmnopqrstuvwxyz">>
> 2> hello:world().
> eheap_alloc: Cannot allocate 2305843009213695256 bytes of memory (of type "heap_frag").
> 
> Crash dump is being written to: erl_crash.dump...done
> make: *** [shell] Error 1

I'm guessing that what I'm trying is wrong but I'd appreciate a pointer as to
why.  I'm motivated in part by comments like the following extract from
enif_make_new_binary():

> The drawbacks are that the binary cannot be kept between NIF calls and it cannot
> be reallocated.

I inferred from this that a binary generated by enif_make_binary() *can* be kept
between NIF calls.  I'm a newcomer to Erlang, if that's not obvious.

Regards,

Robert
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3565 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190208/6dd6a2be/attachment.bin>


More information about the erlang-questions mailing list