This is an example of how to solve the
From Erlang's point of view, the C node is treated like a normal Erlang node. Therefore, 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 Erl_Interface function, 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);
The first argument is the integer which is used to construct the node name. In the example the plain node name will be
The second argument is a string defining the magic cookie.
The third argument is an integer which is used to identify a particular instance of a C node.
If long node node names are used, initiation is done by calling
erl_connect_xinit("idril", "cnode", "cnode@idril.ericsson.se", &addr, "secretcookie", 0);
The first three arguments are the host name, the plain node name, and the full node name. The fourth argument is a pointer to an
The C node can act as a server or a client when setting up the communication Erlang-C. 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) {
Since 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 resulting C programs can be found in looks like the following examples. First a C node server using short node names.
Below follows a C node server using long node names.
And finally we have the code for the C node client.
1. Compile the C code, providing the paths to the Erl_Interface include files and libraries, and to the
In R5B and later versions of OTP, the
In R4B and earlier versions of OTP,
> 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
2. Compile the Erlang code.
unix> erl -compile complex3 complex4
3. Run the C node server example with short node names.
Start the C program
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
4. Run the C node client example. Terminate
unix> cclient (e1@idril)3> complex3:foo(3). 4 (e1@idril)4> complex3:bar(5). 10
5. Run the C node server, long node names, example.
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