<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2000</year><year>2021</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
    
    </legalnotice>

    <title>Erl_Interface</title>
    <prepared></prepared>
    <docno></docno>
    <date></date>
    <rev></rev>
    <file>erl_interface.xml</file>
  </header>

  <p>This section outlines an example of how to solve the example
    problem in <seeguide marker="example">Problem Example</seeguide> by
    using a port and Erl_Interface. It is necessary to read the port
    example in <seeguide marker="c_port">Ports</seeguide> before reading
    this section.</p>

  <section>
    <title>Erlang Program</title>
    <p>The following example shows an Erlang program communicating
      with a C program over a plain port with home made encoding:</p>
      <codeinclude file="complex1.erl" type="erl"/>
    <p>There are two differences when using Erl_Interface on the C
      side compared to the example in <seeguide marker="c_port">
      Ports</seeguide>, using only the plain port:</p>
    <list type="bulleted">
       <item>As Erl_Interface operates on the Erlang external term format,
       the port must be set to use binaries.</item>
       <item>Instead of inventing an encoding/decoding scheme, the
       <c>term_to_binary/1</c> and <c>binary_to_term/1</c> BIFs are to
       be used.</item>
     </list>
    <p>That is:</p>
    <pre>
open_port({spawn, ExtPrg}, [{packet, 2}])</pre>
    <p>is replaced with:</p>
    <pre>
open_port({spawn, ExtPrg}, [{packet, 2}, binary])</pre>
    <p>And:</p>
    <pre>
Port ! {self(), {command, encode(Msg)}},
receive
  {Port, {data, Data}} ->
    Caller ! {complex, decode(Data)}
end</pre>
    <p>is replaced with:</p>
    <pre>
Port ! {self(), {command, term_to_binary(Msg)}},
receive
  {Port, {data, Data}} ->
    Caller ! {complex, binary_to_term(Data)}
end</pre>
    <p>The resulting Erlang program is as follows:</p>
    <codeinclude file="complex2.erl" type="erl"/>
    <p>Notice that calling <c>complex2:foo/1</c> and
      <c>complex2:bar/1</c> results in the tuple <c>{foo,X}</c> or
      <c>{bar,Y}</c> being sent to the <c>complex</c> 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.</p>
  </section>

  <section>
    <title>C Program</title>
    <p>The following example shows a C program communicating with an
    Erlang program over a plain port with the Erlang external term format encoding:</p>
    <codeinclude file="ei.c" type="c"/>
     <p>The following functions, <c>read_cmd()</c> and
      <c>write_cmd()</c>, from the <c>erl_comm.c</c> example in
      <seeguide marker="c_port">Ports</seeguide> can still be
      used for reading from and writing to the port:
    </p>
    <codeinclude file="erl_comm.c" type="c"/>


  </section>

  <section>
    <title>Running the Example</title>
    <p><em>Step 1.</em> Compile the C code. This provides the paths to
      the include file <c>ei.h</c>, and
      also to the library <c>ei</c>:</p>
    <pre>
unix> <input>gcc -o extprg -I/usr/local/otp/lib/erl_interface-3.9.2/include \ </input>
<input>      -L/usr/local/otp/lib/erl_interface-3.9.2/lib \ </input>
<input>      complex.c erl_comm.c ei.c -lei -lpthread</input></pre>
    <p>In Erlang/OTP R5B and later versions of OTP, the <c>include</c>
      and <c>lib</c> directories are situated under
      <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is
      the root directory of the OTP installation
      (<c>/usr/local/otp</c> in the recent example) and <c>VSN</c> is
      the version of the Erl_interface application (3.2.1 in the
      recent example).</p>
    <p>In R4B and earlier versions of OTP, <c>include</c> and <c>lib</c>
      are situated under <c>OTPROOT/usr</c>.</p>
    <p><em>Step 2.</em> Start Erlang and compile the Erlang code:</p>
    <pre>
unix> <input>erl</input>
Erlang (BEAM) emulator version 4.9.1.2

Eshell V4.9.1.2 (abort with ^G)
1> <input>c(complex2).</input>
{ok,complex2}</pre>
    <p><em>Step 3.</em> Run the example:</p>
    <pre>
2> <input>complex2:start("./extprg").</input>
&lt;0.34.0>
3> <input>complex2:foo(3).</input>
4
4> <input>complex2:bar(5).</input>
10
5> <input>complex2:bar(352).</input>
704
6> <input>complex2:stop().</input>
stop</pre>
  </section>
</chapter>

