Ports, NIFs & C Nodes
{packet, 4} adds a 4-byte length header to each message — the external program must read/write that framing.
Port (external program) full (separate OS process) safe integration with any language Port driver (linked-in C) legacy; prefer NIFs none — a crash kills the VM small, fast native functions full (separate node) C program acting as an Erlang node
35.1 Ports
{packet, 4} adds a 4-byte length header to each message — the external program must read/write that framing. Ports are linked to their owner; the external program sees EOF on stdin when the port closes.
Port = open_port({spawn, "python3 -u upper.py"}, [binary, {packet, 4}, exit_status]),
port_command(Port, term_to_binary(hello)),
receive
{Port, {data, Data}} -> binary_to_term(Data);
{Port, {exit_status, S}} -> {exited, S}
end,
port_close(Port).35.2 NIFs
NIFs should return in < 1 ms; otherwise use dirty schedulers (ERL_NIF_DIRTY_JOB_CPU_BOUND / IO_BOUND), yield with enif_schedule_nif, or use threads.
Resource objects (enif_open_resource_type) wrap C pointers with GC-managed destructors.
Safer languages: Rustler (Rust), Zigler (Zig), nifty.
-module(fast_math).
-export([add/2]).
-nifs([add/2]).
-on_load(init/0).
init() -> erlang:load_nif(filename:join(code:priv_dir(myapp), "fast_math"), 0).
add(_A, _B) -> erlang:nif_error(nif_not_loaded).#include <erl_nif.h>
static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
int a, b;
if (!enif_get_int(env, argv[0], &a) || !enif_get_int(env, argv[1], &b))
return enif_make_badarg(env);
return enif_make_int(env, a + b);
}
static ErlNifFunc nif_funcs[] = { {"add", 2, add, 0} };
ERL_NIF_INIT(fast_math, nif_funcs, NULL, NULL, NULL, NULL)35.3 C nodes & jinterface
erl_interface/ei library lets C programs speak the distribution protocol; jinterface does the same for Java.