Search code examples
erlangerlang-nif

Erlang NIF weird iolist behavior


I just started experimenting with Erlang NIFS and got stuck with this problem and I wonder if there's anything one can do about this.

Here is the NIF:

#include "erl_nif.h"

static ERL_NIF_TERM test_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary binary;
    if (!enif_inspect_iolist_as_binary(env, argv[0], &binary)) {
        return enif_make_badarg(env);
    }

    printf("%s\n", binary.data);

    return enif_make_int(env, 0);
}

static ErlNifFunc nif_funcs[] = {
    {"test", 1, test_nif}
};

ERL_NIF_INIT(nif_test, nif_funcs, NULL, NULL, NULL, NULL)

and some outputs when I call the function from erlang:

nif_test:test(<<"helló">>). % hell?
nif_test:test(<<"áéíóöőüű">>). % ?????Q?q
nif_test:test("hello"). % helloErlU?
nif_test:test(""). % xc?
nif_test:test("out"). % outg", "U?

It would be nice to get at least binary strings to work properly. Any ideas?

Edit: I forgot that what I actually need is the data as string (char *) in the C program, so I might have started this off all wrong.


Solution

  • The first two are because printf is not honouring whatever character encoding you're using in your Erlang source file (probably UTF-8).

    The rest are because ErlNifBinary is not null-terminated. You also need to pay attention to binary.size. Something like this:

     printf("%.*s", binary.size, binary.data);