IDL calls routines within a shareable library using the IDL portable calling convention, in which the routine is passed two arguments:


A count of the number of arguments being passed to the routine


An array of argc memory pointers, which are the addresses of the arguments (by reference) or the actual value of the argument (by value) depending on the types of arguments passed to CALL_EXTERNAL and the setting of the VALUE keyword to that function. While all types of data can be passed by reference, there are limitations on data types that can be passed by value, as described in the documentation for CALL_EXTERNAL.

The CALL_EXTERNAL portable convention is necessary because IDL, like any program written in a compiled language, cannot generate arbitrary function calls at runtime. Only calls to interfaces that were known to it when it was compiled are possible. Naturally, most existing C functions are not written to use this interface. Calling such functions typically requires IDL users to write glue functions, the sole purpose of which is to be called by CALL_EXTERNAL with the portable convention, and then to take the arguments and pass them to the real target function using the natural interface for that function. The AUTO_GLUE keyword to CALL_EXTERNAL can be used to generate, compile, and load such glue routines automatically and on demand, without requiring user intervention. Auto Glue is described in Using Auto Glue. AUTO_GLUE does not eliminate the need for, or use of, the portable convention, but it can relieve the IDL user of the requirement to handle it explicitly. The end result is that calling existing function interfaces is easier to do, and less error prone.

Routines called by CALL_EXTERNAL with the portable convention are defined with a prototype similar to the following:

return_type example(int argc; void *argv[])

where return_type is one of the data types which CALL_EXTERNAL can return. If this return_type is not IDL_LONG, a keyword must be used in the CALL_EXTERNAL call to indicate the actual type of the result.

The parameter argc gives the number of arguments passed to the external routine by CALL_EXTERNAL in the argv array, while argv is an array containing the arguments. Arguments are passed either by value or by reference. Those passed by value are copied directly into the argv array, with the exception of scalar strings, which place a pointer to a null-terminated string in argv[i]. All arrays are passed by reference. Scalar items passed by reference (the default) place a pointer to the datum in argv[i]. Strings and string arrays passed by reference place a pointer to an IDL_STRING structure in argv[i]. This structure is defined as follows:

typedef struct {
  IDL_STRING_SLEN_T slen;	/* Length of string */
  short stype;	/* type of string:	(0) static, (!0) dynamic */
  char *s;	/* Addr of string, invalid if slen == 0.	*/

See CALL_EXTERNAL for additional details about passing parameters by value.

It is important to note that IDL integer variables correspond to a 16-bit integer (a C signed short integer). For example, an integer variable could be defined in an IDL routine as follows:

IDL> A = 5	;default type of integer, not LONG

The variable could then be passed by reference in a CALL_EXTERNAL call. The declaration and cast statement in the called C routine should be:

short *a;
a = (short *) argv[0];


a = (IDL_INT *) argv[0];

IDL_INT corresponds to a C short (16-bit integer), so either form is correct. The corresponding type in Fortran would be INTEGER*2.