This section outlines an example of how to solve the example
problem in
From Erlang's point of view, the C node is treated like a
normal Erlang node. Thus, calling the functions
{RegName, Node} ! Msg
The node name
The registered name,
When using long node names, the code is slightly different as shown in the following example:
Before calling any other function in Erl_Interface, the memory handling must be initiated:
erl_init(NULL, 0);
Now the C node can be initiated. If short node names are
used, this is done by calling
erl_connect_init(1, "secretcookie", 0);
Here:
In the example, the plain node name is
If long node node names are used, initiation is done by
calling
erl_connect_xinit("idril", "cnode", "cnode@idril.ericsson.se", &addr, "secretcookie", 0);
Here:
The C node can act as a server or a client when setting up
the Erlang-C communication. If it acts as a client, it
connects to an Erlang node by calling
fd = erl_connect("e1@idril");
If the C node acts as a server, it must first create a socket
(call
erl_publish(port);
Now the C node server can accept connections from Erlang nodes:
fd = erl_accept(listen, &conn);
The second argument to
The C node can receive a message from Erlang by calling
It is also necessary to take care of the types
while (loop) { got = erl_receive_msg(fd, buf, BUFSIZE, &emsg); if (got == ERL_TICK) { /* ignore */ } else if (got == ERL_ERROR) { loop = 0; /* exit while loop */ } else { if (emsg.type == ERL_REG_SEND) {
As the message is an
fromp = erl_element(2, emsg.msg); tuplep = erl_element(3, emsg.msg); fnp = erl_element(1, tuplep); argp = erl_element(2, tuplep); if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) { res = foo(ERL_INT_VALUE(argp)); } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) { res = bar(ERL_INT_VALUE(argp)); } resp = erl_format("{cnode, ~i}", res); erl_send(fd, fromp, resp);
Finally, the memory allocated by the
erl_free_term(emsg.from); erl_free_term(emsg.msg); erl_free_term(fromp); erl_free_term(tuplep); erl_free_term(fnp); erl_free_term(argp); erl_free_term(resp);
The following examples show the resulting C programs. First a C node server using short node names:
A C node server using long node names:
Finally, the code for the C node client:
Step 1. Compile the C code. This provides the paths to
the Erl_Interface include files and libraries, and to the
> gcc -o cserver \\ -I/usr/local/otp/lib/erl_interface-3.2.1/include \\ -L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ complex.c cnode_s.c \\ -lerl_interface -lei -lsocket -lnsl unix> gcc -o cserver2 \\ -I/usr/local/otp/lib/erl_interface-3.2.1/include \\ -L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ complex.c cnode_s2.c \\ -lerl_interface -lei -lsocket -lnsl unix> gcc -o cclient \\ -I/usr/local/otp/lib/erl_interface-3.2.1/include \\ -L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ complex.c cnode_c.c \\ -lerl_interface -lei -lsocket -lnsl
In Erlang/OTP R5B and later versions of OTP, the
In R4B and earlier versions of OTP,
Step 2. Compile the Erlang code:
unix> erl -compile complex3 complex4
Step 3. Run the C node server example with short node names.
Do as follows:
unix> cserver 3456 unix> erl -sname e1 -setcookie secretcookie Erlang (BEAM) emulator version 4.9.1.2 Eshell V4.9.1.2 (abort with ^G) (e1@idril)1> complex3:foo(3). 4 (e1@idril)2> complex3:bar(5). 10
Step 4. Run the C node client example. Terminate
unix> cclient (e1@idril)3> complex3:foo(3). 4 (e1@idril)4> complex3:bar(5). 10
Step 5. Run the C node server example with long node names:
unix> cserver2 3456 unix> erl -name e1 -setcookie secretcookie Erlang (BEAM) emulator version 4.9.1.2 Eshell V4.9.1.2 (abort with ^G) (e1@idril.du.uab.ericsson.se)1> complex4:foo(3). 4 (e1@idril.du.uab.ericsson.se)2> complex4:bar(5). 10