All of the code for the examples in this section can be found in the /external/call_external/C subdirectory of the IDL distribution. Please read the README file in that directory for details on how to run the examples. In many cases, the files in that directory go into more detail, and are more fully commented than the versions shown here. Also, the examples provide IDL wrapper routines that perform the necessary CALL_EXTERNAL calls, while the examples shown here use CALL_EXTERNAL directly in order to explain how it is used. It is worth reading the contents of the .c and IDL .pro files in that directory in addition to reading the code shown here.

Example: Passing Parameters by Reference to IDL


The following routine, found in simple_vars.c, accepts several of IDL’s basic data types as arguments. The parameters are passed in by reference and the new squared values of the numbers are passed back to IDL. 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"	/* IDL external definitions */
  int simple_vars_natural(char *byte_var, short *short_var, 
     IDL_LONG *long_var, float *float_var, double *double_var)
  {
  /* Square each variable. */
  *byte_var	*= *byte_var;
  *short_var	*= *short_var;
  *long_var	*= *long_var;
  *float_var	*= *float_var;
  *double_var	*= *double_var;
  return 1;
  }
  int simple_vars(int argc, void* argv[])
  {
  /* Insure that the correct number of arguments were passed in */
  if(argc != 5) return 0;
  return simple_vars_natural((char *) argv[0], (short *) argv[1], (IDL_LONG *) argv[2], (float *) argv[3],
  (double *) argv[4]);
}

 

The IDL statements necessary to call the simple_vars() function from IDL can be written:

B=2B & I=3 & L=3L & F=0.0 & D=0.0D
R = CALL_EXTERNAL(GET_CALLEXT_EXLIB(), ’simple_vars’, $
   b,i,l,f,d, /CDECL)

Note: GET_CALLEXT_EXLIB() is a function provided with the CALL_EXTERNAL examples; it builds the necessary sharable library of external C code and returns the path to the library as its result.

Using the AUTO_GLUE keyword to CALL_EXTERNAL, you can call the function with the natural C interface directly:

B=2B & I=3 & L=3L & F=0.0 & D=0.0D
R = CALL_EXTERNAL(GET_CALLEXT_EXLIB(), ’simple_vars_natural’, $
   b,i,l,f,d, /CDECL, /AUTO_GLUE)

Example: Calling a C Routine to Perform Computation


The following example demonstrates an external function that returns the sum of a floating point array. It is similar in function to the TOTAL function in IDL. The code for this example is found in the file sum_array.c in the IDL distribution. As with the previous example, this function is implemented by a function that has a natural C interface, and a second glue function is provided that matches the IDL portable calling convention to the natural interface:

#include <stdio.h>
#include "idl_export.h"
   
  float sum_array_natural(float *fp, IDL_LONG n)
  {
  float s = 0.0;
   
  	while (n--) s += *fp++;
  	return(s);
  	}
   
  	float sum_array(int argc, void *argv[])
  	{
  	return sum_array_natural((float *) argv[0], (IDL_LONG) argv[1]);
	}

The IDL statements necessary to call the sum_array() function from IDL can be written:

X = FINDGEN(10)
S = CALL_EXTERNAL(GET_CALLEXT_EXLIB(), ’sum_array’$
   X, N_ELEMENTS(X),VALUE=[0,1], /F_VALUE, /CDECL)

 

Note: GET_CALLEXT_EXLIB() is a function provided with the CALL_EXTERNAL examples; it builds the necessary sharable library of external C code and returns the path to the library as its result.

Using the AUTO_GLUE keyword, you can call the function with the natural C interface directly:

X = FINDGEN(10)
S = CALL_EXTERNAL(GET_CALLEXT_EXLIB(), ’sum_array_natural’$
   X, N_ELEMENTS(X),VALUE=[0,1], /F_VALUE,/CDECL,$
   /AUTO_GLUE)

In this example, sum_array and sum_array_natural are the names of the entry points for the external functions, and X and N_ELEMENTS(X) are passed to the called routine as parameters. The F_VALUE keyword specifies that the returned value is a floating-point number rather than an IDL_LONG.