A
typemap translates between
types in different
programming languages. We typically need to do this if we want to
call code written in one programming language (say
C or
C++) from code written in another programming language (say
Perl or
Python). Note that we have to transfer data in
both directions: a
function both receives and transmits data!
Tools such as Swig (for calling C and C++ from Perl, Python, TCL, Guile) and XS (for calling C and C++ from Perl) employ typemaps as a structured way of presenting these conversions.
The mapping is sometimes reasonably simple: a C int should map to an integer scalar in Perl (an IV, a type of SV). Usually it isn't. A 64 bit integer value in C is too large to fit into a double precision IEEE floating point field, so it cannot directly be converted to a Perl numeric scalar. But you'll still probably want to do just that in many cases.
Sometimes the mapping involves intent, not just type; you use a named typemap for these cases. C pointers provide the clearest instance. Say I have a parameter of type double *. It can be any of the following:
- A pointer to the first element of a 3-element vector being passed into the function.
- A pointer to the first element of an array being passed into the function, the size of which is in another variable.
- Either of the above, but denoting memory locations in which a vector is returned.
- The above, but used both for input and for output.
- A double being passed as if it were a Pascal ref ("call by reference") parameter.
char * pointers are even worse -- they could also refer to
NUL terminated strings!
Additionally, it's potentially unclear whether the C function expects to be able to free the pointer, or if it expects the caller to free it.
Perl supports multiple return values (by returning a list), while C doesn't (and uses pointers instead); how should the C function be called?
The solution is to provide separate typemaps for these cases; when "wrapping" the code the correct typemap must be specified. This complexity is inherent in the problem, not in the solution!
See an example of type mapping for a simple specific example.