When you pass an IDL array into a CALL_EXTERNAL routine, that routine gets a pointer to the first memory location in the array. In order to perform any processing on the array, an external routine needs more information—such as the array’s size and number of dimensions. With CALL_EXTERNAL, you will need to pass this information explicitly as additional arguments to the routine.

In order to handle multi-dimensional arrays, C needs to know the size of the array at compile time. In most cases, this means that you will need to treat multi-dimensional arrays passed in from IDL as one dimensional arrays. However, you can still build your own indices to access an array as if it had more than one dimension in C. For example, the IDL array index:

array[x,y]

could be represented in a CALL_EXTERNAL routine as:

array_ptr[x + x_size*y];

The following routine, found in sum_2d_array.c, calculates the sum of a subsection of a two dimensional array. This is implemented as a function with a natural C interface, and a second glue routine that implements the IDL portable convention, using the one with the natural interface to do the actual work:

 

 #include <stdio.h>
	#include "idl_export.h"
	double sum_2d_array_natural(double *arr, IDL_LONG x_start, IDL_LONG x_end,
	IDL_LONG x_size, IDL_LONG y_start,
	IDL_LONG y_end, IDL_LONG y_size)
	/* Since we didn’t know the dimensions of the array at compile time, we
	* must treat the input array as if it were a one dimensional vector. */
	IDL_LONG x,y;
	double result = 0.0;
 
	/* Make sure that we don’t go outside the array.strictly speaking, this
	*is redundant since identical checks are performed in the IDL wrapper
	* routine.IDL_MIN() and IDL_MAX() are macros from idl_export.h */
	x_start = IDL_MAX(x_start,0);
	y_start = IDL_MAX(y_start,0);
	x_end = IDL_MIN(x_end,x_size-1);
	y_end = IDL_MIN(y_end,y_size-1);
 
	/* loop through the subsection */
	for (y = y_start;y <= y_end;y++)
	for (x = x_start;x <= x_end;x++)
	result += arr[x + y*x_size]; /* build the 2d index: arr[x,y] */
	return result;
	}
 
	double sum_2d_array(int argc,void* argv[])
	{
	if (argc != 7) return 0.0;
	return sum_2d_array_natural((double *) argv[0], (IDL_LONG) argv[1],
	(IDL_LONG) argv[2], (IDL_LONG) argv[3],
	(IDL_LONG) argv[4], (IDL_LONG) argv[5],
	(IDL_LONG) argv[6]);
	}

The IDL system routine interface provides much more support for the manipulation of IDL array variables.