Hacker News new | ask | show | jobs
by kuon 605 days ago
I don't have open source code base to share but here it how it looks like:

        // the_nif.zig

        fn init_imp(
            env: ?*erl.ErlNifEnv,
            argc: c_int,
            argv: [*c]const erl.ERL_NIF_TERM,
        ) !erl.ERL_NIF_TERM {
            if (argc != 0) {
                return error.BadArg;
            }

            return try helpers.make("Hello world");
        }

        export fn media_tools_init(
            env: ?*erl.ErlNifEnv,
            argc: c_int,
            argv: [*c]const erl.ERL_NIF_TERM,
        ) erl.ERL_NIF_TERM {
            return init_imp(env, argc, argv) catch |err|
                return helpers.make_error(env, err);
        }


        var funcs = [_]erl.ErlNifFunc{ erl.ErlNifFunc{
            .name = "init",
            .arity = 1,
            .fptr = media_tools_init,
            .flags = erl.ERL_NIF_DIRTY_JOB_CPU_BOUND, 
        } };

        var entry = erl.ErlNifEntry{
            .major = erl.ERL_NIF_MAJOR_VERSION,
            .minor = erl.ERL_NIF_MINOR_VERSION,
            .name = "Elixir.MediaTools.Stream",
            .num_of_funcs = funcs.len,
            .funcs = &funcs,
            .load = load,
            .reload = null,
            .upgrade = null,
            .unload = null,
            .vm_variant = "beam.vanilla",
            .options = 0,
            .sizeof_ErlNifResourceTypeInit = @sizeOf(erl.ErlNifResourceTypeInit),
            .min_erts = "erts-10.4",
        };

        export fn nif_init() *erl.ErlNifEntry {
            return &entry;
        }

        # the_exlixir_file.ex

        assert "Hello world" == MediaTools.Stream.init()

The "helpers" library is used to convert types to and from erlang, I plan on open sourcing it but it is not ready now. In the above example, the code is explicit but "entry" can be created with an helper comptime function. erl is simply the erl_nif.h header converted by zig translate-c.

I wrote a piece back in 2022, but things evolved a lot since then: https://www.kuon.ch/post/2022-11-26-zig-nif/

2 comments

This won't work on Windows as the BEAM uses a slightly different NIF initialisation method there.
Thanks for sharing the post, it was intriguing. The detailed comments mentioned in `main.zig` and `build.zig` towards the end helped a lot.