Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I use zig a lot in elixir nif, for things like audio and video processing

Sounds interesting, is it open source? I am interested in seeing how the code layout looks like when mixing Zig and Elixir



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/


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: