mat-hek

mat-hek

Membrane Core Team

Unifex - same code for NIFs and C nodes

Hello everyone,

pleased to announce Unifex, a tool that simplifies integrating elixir with C/C++. Unifex has been out for some time already but since v0.3 released today, it supports generating C nodes - lightweight programs acting as Erlang nodes. Though communication with NIFs is way faster than with separate nodes, a failing node doesn’t crash the entire VM, moreover, it can be supervised like a normal process. Unifex allows choosing between NIFs and C nodes at any point, even in runtime.

Approach

Here are some key facts about Unifex:

  • Native code is kept separate from elixir code
  • Native code doesn’t depend on erlang libraries, but on Unifex abstraction, that aims to be more user friendly than erlang APIs
  • Unifex works by generating boilerplate code in the compile-time, based on DSL in elixir
  • Unifex aims to support the intersection of sets of data types from Elixir and C
  • Unifex relies on Bundlex, our tool for compiling native code

Here’s how it looks like in short: firstly, you describe the interface with spec-like DSL:

module Example

interface [NIF, CNode]

spec foo(num :: int) :: {:ok :: label, answer :: int}

then you provide implementation:

#include "_generated/example.h"

UNIFEX_TERM foo(UnifexEnv* env, int num) {
  return foo_result_ok(env, num);
}

and finally, you use it either as NIF

defmodule Example do
  use Unifex.Loader
end
iex> Example.foo(10)
{:ok, 10}

or as CNode

iex> require Unifex.CNode
iex> {:ok, cnode} = Unifex.CNode.start_link(:example)
iex> Unifex.CNode.call(cnode, :foo, [10])
{:ok, 10}

A detailed description of how to place that in a Mix project can be found here.

Use cases

We’re using Unifex heavily at Membrane, mainly for wrapping some complex, stateful libs, and that’s where Unifex suits the most IMHO.

Status

Though we’ve been using Unifex for NIFs for some time, adding C nodes required lots of changes that are quite fresh. We’re validating them while developing Membrane ICE plugin.

Feedback and contributions are most welcome :wink:

Credits: @Feliks, @mickel8, @bblaszkow06, @mkaput, Software Mansion

Most Liked

mat-hek

mat-hek

Membrane Core Team

Unifex v0.4.0 released :tada:

This version adds the ability to define custom types and use them in Unifex specs. For now, enums and structs are supported. Declaring them generates C enums and C structs, respectively, for example:

type position :: :manager | :developer | :intern | :product_owner

type personal_data :: %PersonalData{
  age: int,
  expirience: int,
  name: string
}

will generate

enum Position_t { MANAGER, DEVELOPER, INTERN, PRODUCT_OWNER };
typedef enum Position_t Position;

struct personal_data_t {
  int age;
  int expirience;
  char *name;
};
typedef struct personal_data_t personal_data;

and can be used like

spec get_salary(person :: personal_data, person_position :: position) ::
       {:ok :: label, salary :: int}
       | {:error :: label, :unemployed :: label}

Docs, GitHub

Credits go to @Feliks, thanks!

Where Next?

Popular in Libraries Top

New
Qqwy
TypeCheck: Fast and flexible runtime type-checking for your Elixir projects. Core ideas Type- and function specifications are const...
336 13801 100
New
dbern
I’m excited to announce that TaxJar has developed and open-sourced DateTimeParser. We developed it because we found a need to parse user ...
New
tmbb
I’ve been working on two packages (not on hex.pm yet) to build admin interfaces for phoenix apps: bureaucrat - which contains a bunch ...
New
Crowdhailer
Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure). 1.0-rc.1 is now available. To use it re...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. Features Unstyled Phoenix components. Storybook that can be added to...
New
pkrawat1
Presenting Aviacommerce, open source e-commerce platform in Elixir Aviacommerce is an open source e-commerce platform in Elixir. We at...
New
josevalim
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below. Hi everyone, We a...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
anshuman23
Hello all, I have been working on my proposed project called Tensorflex as part of Google Summer of Code 2018.. Tensorflex can be used f...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

Sub Categories:

We're in Beta

About us Mission Statement