简体   繁体   中英

Why does `erl_decode` return NULL when deserializing an Elixir map?

I'm trying to move some data between an Elixir program and a C program. In Elixir, I have a struct of stuff I want to move over. I use :erlang.term_to_binary to convert it to a binary that I then mash over to C.

However, when I decode it, it just returns NULL ?? And there's no error message or anything. A bunch of other elixir/erlang terms work fine; it specifically fails when I try to send over a map or a struct (which is a type of map).

I'm doing something like this in Elixir:

  msg = %Message{ title: "hello", body: "world" }
  binmsg = :erlang.term_to_binary(msg)
  send(state.port, {self(), {:command, binmsg}})

.. and in C (excluding the receiving of the message, which I have confirmed has arrived with the correct length, and even confirmed that the bytes are identical in C and elixir):

  uint8_t *buf = read_cmd();
  ETERM *map = erl_decode(buf);
  erl_print_term(map, stdout);

It seems from the source code of erl_decode that it does not support deserializing maps. Maps ARE defined in Erlang's binary protocol as of Erlang/OTP 17, but there is no mention of MAP_EXT inside erl_marshal.c .

This is likely because erl_marshal is hella legacy, and has been deprecated since Erlang/OTP 22. Please use the ei_decode_* family of functions instead! There's even a ei_decode_map_header . That should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM