1 Overview
The Interface Generator (IG) is a tool which makes it easier to interface C with Erlang. With IG, it is possible to transparently access the "other" language directly. C functions look like Erlang functions on the Erlang side, and Erlang functions look like C functions on the C side. IG accomplishes this by generating interface stubs on both sides. These stubs will then handle all communication and parameter passing between Erlang and C.
The IG Generated StubsA header file defines the interface for which IG generates stubs. This header file is a real C header file which is included in user's C code. The header file must be augmented with some IG keywords, but it otherwise looks like a normal C header file. The keywords do not disturb normal C header file duties. Currently, IG does not handle the complete ANSI C syntax, but a subset thereof.
IG generates interface stub code on both the Erlang side and the C side. The stub code then takes care of argument marshalling and the routing of function calls. The stub on the Erlang side contains the interface functions and acts as shadow for the "real" C functions. When an Erlang stub function is called, it sends a request for the function call to the C stub. The C stub does the real function call and passes the result back to Erlang. The IG stubs uses the standard Erlang
port
mechanism for its communication, but this can be changed to sockets if required.
The Call ChainRefer to the IG distribution which contains many examples. The reader is recommended to read through and run these examples.
1.1 IG Basics
IG works by generating stub files from a C header file which includes some added IG keywords. Two, and possibly three, files are normally produced:
- the Erlang stub which is an Erlang
.erl
file- the C stub which is a C
.c
file- an optional Erlang
.hrl
header file which is produced if pre-processor macros or struct types are used.IG reads the input header file and interprets the keywords which serve as guides for the generator. They are needed because more information than is normally present in a C header file is needed for the stub generation.
The following section provides a quick summary of all the IG keywords and small examples of their use. The examples include most constructs. These examples illustrate what is written in an IG header file.
1.1.1 Keywords Used in Erlang to C Situations
- IG_fun
- This keyword marks a function as accessible from Erlang.
IG_fun int plus(int a, intb);
means that the functionplus
can be called in Erlang.- IG_void
- This keyword marks a function as accessible from Erlang, but the function does not return a value. It is a one-way call as shown in the example
IG_void void do_it();
- /*IG_var*/
- This keyword marks a C variable as accessible from Erlang. The function call generates a get and set function in Erlang. Example:
/*IG_var*/ extern int my_int;
. The variable must be declared extern.1.1.2 Keywords Used in C to Erlang Situations
- IG_call
- This keyword marks a function as accessible from C.
IG_call int get_time();
is in effect a declaration of an Erlang function.- IG_cast
- One-way call of an Erlang function. It is to
IG_call
whatIG_void
is toIG_fun
. Example:IG_cast void throw_msg(IG_string str);
1.1.3 General Keywords and Types
- /*IG*/
- The
/*IG*/
comment keyword is used together with pre-processor directives./*IG*/ #define PI 3.14
defines an Erlang macro with the namePI
. Note the space after the comment. The definitions are generated to the.hrl
file only.- IG_binaryPtr
- The C type definition of the Erlang binary type, which can be used to pass large chunks of memory to and from Erlang. This is not really a keyword, but rather an IG type definition. Example:
IG_fun IG_binaryPtr get_state();
- IG_string
- This is used for the C
char*
type when the type means a character string as opposed to those that are really pointers to bytes. Do not useIG_string
whenchar*
denotes a arbitrary pointer to bytes. For example, the declarationIG_fun IG_string get_version_str();
tells IG that the functionget_version
returns a NULL terminated string so that IG will build an Erlang string of the characters. Ifchar*
is used, then IG treats the return value as an opaque pointer instead of trying to build an Erlang string of the characters.- struct
- While the
struct
keyword is not really an IG keyword, IG will generate Erlang records for every struct type declaration it sees. Records are generated to the.hrl
file only.The IG keywords enable IG to generate stubs which handle all communication link set-up, message passing, marshalling of arguments, and return values.
The design philosophy of IG is to make important aspects of C valid in Erlang, and to find solutions which ensure that it feels natural to use C with Erlang.
1.1.4 A Hands-On Example
This section describes an example which might help in understanding the basic behaviour of IG. Readers can skip this section at their own discretion.
This simple example calls the C function
foo
from Erlang and goes through all steps, from the header file to the final call offoo
from Erlang. The first step is to write the header file which defines the interface tofoo
. We do this in a file calledex1.h
which looks as follows:IG_fun int foo(IG_string name, int age);This means that
foo
can be called from Erlang. The next step is to write the actual definition offoo
. We will place this definition in the fileex1.c
which looks as follows:#include <stdio.h> #include "ig.h" IG_fun int foo(IG_string name, int age) { fprintf(stderr, "foo: name='%s', age=%d\n", name, age); return age; }
We use
stderr
to print the string because IG usesstdin
andstdout
for its port communication with Erlang. This can be configured (see also Sockets in Advanced IG Topics).The stubs are then generated in an Erlang shell:
UNIX> erl Erlang (JAM) emulator version 4.4.2 Eshell V4.4.2 (abort with ^G) 1> ig:gen(ex1). Calling parser C symbol allocation........... Generating C code........... Generating callbacks C code generated to file: ex1_stub.c Generating Erlang code. Erlang code generated to file: ex1.erl Generator ready ok 2>We now have an Erlang stub called
ex1.erl
and a C stub calledex1_stub.c
. These must be compiled into an Erlangjam
file and an executable file. We begin by compiling the Erlang file in the Erlang shell:2> c(ex1). {ok,ex1}The C stub is then compiled and linked into an executable in a Unix shell:
UNIX> gcc -L. -o ex1 ex1.c ex1_stub.c igio.o igmain.o -lerl_interface UNIX>This produces an executable
ex1
which implements thefoo
function. Theig.h
,igio.o
,igmain.o
, anderl_interface
files are part of the IG magic. They contain the declarations, the IO routines, the main loop, and the value representation. These are files from the IG distribution. The reader will have to find the place where IG was installed and then try theusr/include
directory for theig.h
file, and theusr/lib
for the object files and libraries. We have OTP installed at/home/super/otp/otp_sunos5
, so we find theig.h
file in the/home/super/otp/otp_sunos5/usr/include
directory.We are now ready to run the example from Erlang. We start the stubs from Erlang and note that this also starts the C program:
3> P=ex1:start(). <0.22.0> 4> ex1:foo(P, "Nils", 34). foo: name='Nils', age=34 {ok,34} 5>The
foo
function has one more parameter than its C counterpart and this is the handle to the C program. The return value is the tuple{ok,34}
.In summary, the steps for using IG are:
- write the header file
- write the C implementation
- generate the stubs
- compile the stubs into
jam
and an executable C program- start the program from an Erlang shell.