2 Using C from Erlang
This section describes the inclusion of C programs in Erlang and includes the following topics:
- Calling C functions
- Access to C variables
- Pointers, struct types and records
- Erlang binaries.
2.1 Calling C Functions
Most commonly, IG is used for accessing functions which are written in C. These include sourced software which must be interfaced with Erlang, or certain routines which must be written in C for some reason.
The interface to be IG generated is written in a standard C header file with the appropriate IG keywords. Most of the time, this only involves writing
IG_fun
in front of the function declarations in the header file that is part of the interface which is called from Erlang. These will then be accessible from Erlang and IG includes them in both of the stub files generated. When IG encountersIG_fun int hello();
in a header file, it puts a shadow functionhello
in the Erlang stub and makes a "real" call to thehello
function in the C stub. Thehello
function is a normal C function which can be called from C without any overhead and the header file is still a valid C header file. If the C function is a "one-way" function, which means that we are not interested in the return value and we do not want to wait for completion, then the IG keywordIG_void
may be used instead. In this case, the generated Erlang stub will not block and wait for an answer, but returns to the calling party immediately.2.2 Access to C Variables
The IG keyword
/*IG_var*/
gives access to global C variables. By using this keyword, IG generates access methods (get and set) for the variable into its stubs. It is also possible to get the address and size of the variable to Erlang.Variables are marked for generation by the keyword
/*IG_var*/
. If/*IG_var*/ extern int my_count;
is a variable in the input header file, then IG will generate stub code functionsmy_count/1
andset_my_count/2
. These stub code functions will get and set themy_count
variable.
There are no checks made for concurrent updates of the variable. This means that both sides must not set the value of the variable at the same time.
In summary, the following things can be done in Erlang with a
/*IG_var*/
declared variable:
- get and set its value
- get its address as a pointer
- get its size from the C
sizeof
operator.2.3 Pointers, Struct Types and Records
IG treats pointers as integers and allows them to be passed around. IG will not "understand" what the pointers point to, but it is sometimes useful to be able to pass the pointer around to the next C function call. Be careful that the data the pointer points to is not de-allocated or otherwise freed before use.
C structs are translated to Erlang records to allow symbolic access to members of the structs. The translation is straight forward. Include the following code in the header file:
typedef struct { int len; IG_string name; } person;The following Erlang record will then be generated to an Erlang
.hrl
header file:-record(person, {len,name}).The record person can now be used as arguments to functions and return values from functions. IG will generate packing and unpacking of the record values on both sides.
2.4 Erlang Binaries
Erlang binaries are data structures which can be used for passing large pieces of data to and from Erlang. It is defined in C as a struct with a size and a data pointer. The binary structure corresponds to the Erlang binary base type and it can therefore work both ways:
- C can pass opaque data to Erlang
- Erlang can pass Erlang terms hidden in binaries to C.
The
IG_binaryPtr
type is defined inig.h
as:typedef struct { int size; unsigned char *binp; } *IG_binaryPtr;IG itself uses binaries when passing data between Erlang and C.