There are three ways to call C routines from e:
You can declare a global e routine to be implemented as a C routine. In this case, you can call the C routine directly from anywhere in your e code.
You can declare a local e method to be implemented as a C routine. In this case, you define an e method within a struct and indicate that the method's body is implemented as a C routine. When you call the e method, the name of the enclosing struct instance is passed to the C routine and the C routine is executed. This way of calling C routines is useful when the C routine manipulates the fields of a particular struct instance.
You can declare a local e method to be implemented as a dynamic C routine or foreign dynamic C routine. Dynamic C routines are not discussed in this chapter.
A global e routine statement is declared with a specified name, parameters, and result type. The body of the global e routine is implemented by the specified C routine. The syntax for a global e routine is as follows:
routine e-routine-name(param, ...) [:result-type] [is C routine c-routine-name];
If the optional "is C routine c-routine-name" is omitted, the assumed name of the C routine is the e-routine-name. A global e routine is a statement, not a struct member declaration. An example of a global e routine was discussed in "Integrating C Files" on page 290.
A e method can be declared in such a way that when the e method is called, the C routine is executed. The syntax for defining an e method using a C routine is as follows:
e-method-name(param,...)[:result-type] is C routine c-routine-name ;
The construct method ... is C routine is a struct member, not a statement declaration unlike a global e routine. Example 16-10 shows the usage of an e method implemented with use of a C routine. This example shows how to call a C routine, proprietary_encrypt, to encrypt the data field of a struct packet.
File name: encrypt.c #include <stdio.h> #include "encrypt_.h" SN_TYPE(byte) proprietary_encrypt( /*Define C routine*/ SN_TYPE(packet) packet1, SN_TYPE(byte) data ) { return( data + 8); }; ------------------------------------------------------------------ File name: encrypt.e <' import packet; struct packet { kind : [good,bad]; addr : uint (bits : 2) ; len : uint (bits : 6) ; data [len] : list of byte ; !parity : byte ; -- Declare method encrypt of struct packet that is implemented -- using the C routine proprietary encrypt. encrypt( byte ):byte is C routine proprietary_encrypt; post_generate() is { out("Encrypting data: before -\n",data); -- unencrypted data for each (d) in data { data[index] = encrypt( d ); -- Call encrypt method -- like a regular e method }; out("after -\n",data); -- Print the encrypted data };// post_generate }; // packet extend sys { packets: list of packet; -- Instantiate a list of packets keep packets.size() == 5; -- Constrain the size of list }; '>