[erlang-questions] Question on Erlang Port Drivers

Vance Shipley vances@REDACTED
Fri Jan 27 11:01:30 CET 2012

On Thu, Jan 26, 2012 at 10:40:12PM +0530, Vance Shipley wrote:
}  Using port_command/2, or 'Port ! {PortOwner, {command, Data}}', is
}  the best solution for a driver which is handling a stream of data
}  or transactions where you can have a flying window.

Of course that's both only my opinion and only a rule of thumb.
Some would argue that pure messaging is the truly functional way.

}  Changing Argument to a double could be done by lengthening the list
}  to handle the size of a double.  Something like [Command, Arg0, Arg1,
}  Arg2, Arg3, Arg4, Arg5, Arg6, Arg7], and you'd need to handle mapping
}  the eight bytes from a double.  But that would all be messy and not
}  portable.

You can stick with this method of message passing by opening the port
in binary mode and encoding with the external term format.  To open
the port in binary mode just add the option to open_port/2:

   Port = open_port({spawn, SharedLib}, [binary]),

Change to encode your terms in the external term format and send as
a binary:

   encode(Arg) -> term_to_binary(Arg).

   decode(Result) -> binary_to_term(Result).

In the example_drv_output() function of port_driver.c decode the 
received buffer as an external term format:

   if (ei_decode_version(buf, &index, &version)
           || ei_decode_tuple_header(buf, &index, &arity) || arity != 3
           || ei_decode_atom(buf, &index, &cmd)
           || ei_decode_double(buf, &index, &arg))

Return the result the same way:

   rbuf = driver_alloc_binary(size);
   if (ei_encode_version(rbuf, &index)
           || ei_encode_double(*rbuf, &index, res))
      driver_output_binary(d->port, rbuf, index);


More information about the erlang-questions mailing list