# 5 Erl_Interface

This section outlines an example of how to solve the example problem in Problem Example by using a port and Erl_Interface. It is necessary to read the port example in Ports before reading this section.

###
5.1 Erlang Program

The following example shows an Erlang program communicating with a C program over a plain port with home made encoding:

There are two differences when using Erl_Interface on the C side compared to the example in Ports, using only the plain port:

- As Erl_Interface operates on the Erlang external term format, the port must be set to use binaries.
- Instead of inventing an encoding/decoding scheme, the term_to_binary/1 and binary_to_term/1 BIFs are to be used.

That is:

    open_port({spawn, ExtPrg}, [{packet, 2}])

is replaced with:

    open_port({spawn, ExtPrg}, [{packet, 2}, binary])

And:

    Port ! {self(), {command, encode(Msg)}},
    receive
      {Port, {data, Data}} ->
        Caller ! {complex, decode(Data)}
    end

is replaced with:

    Port ! {self(), {command, term_to_binary(Msg)}},
    receive
      {Port, {data, Data}} ->
        Caller ! {complex, binary_to_term(Data)}
    end

The resulting Erlang program is as follows:

Notice that calling complex2:foo/1 and complex2:bar/1 results in the tuple {foo,X} or {bar,Y} being sent to the complex process, which codes them as binaries and sends them to the port. This means that the C program must be able to handle these two tuples.

###
5.2 C Program

The following example shows a C program communicating with an Erlang program over a plain port with the Erlang external term format encoding:

The following functions, read_cmd() and write_cmd(), from the erl_comm.c example in Ports can still be used for reading from and writing to the port:

###
5.3 Running the Example

Step 1. Compile the C code. This provides the paths to the include file ei.h, and also to the library ei:

    unix> gcc -o extprg -I/usr/local/otp/lib/erl_interface-3.9.2/include \
          -L/usr/local/otp/lib/erl_interface-3.9.2/lib \
          complex.c erl_comm.c ei.c -lei -lpthread

In Erlang/OTP R5B and later versions of OTP, the include and lib directories are situated under OTPROOT/lib/erl_interface-VSN, where OTPROOT is the root directory of the OTP installation (/usr/local/otp in the recent example) and VSN is the version of the Erl_interface application (3.2.1 in the recent example).

In R4B and earlier versions of OTP, include and lib are situated under OTPROOT/usr.

Step 2. Start Erlang and compile the Erlang code:

    unix> erl
    Erlang (BEAM) emulator version 4.9.1.2

    Eshell V4.9.1.2 (abort with ^G)
    1> c(complex2).
    {ok,complex2}

Step 3. Run the example:

    2> complex2:start("./extprg").
    <0.34.0>
    3> complex2:foo(3).
    4
    4> complex2:bar(5).
    10
    5> complex2:bar(352).
    704
    6> complex2:stop().
    stop