[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