Previous External Development Guide: Using CALL_EXTERNAL Next

Passing Structures

IDL structure variables are stored in memory in the same layout that C uses. This makes it possible to pass IDL structure variables into CALL_EXTERNAL routines, as long as the layout of the IDL structure is known. To access an IDL structure from an external routine, you must create a C structure definition that has the exact same layout as the IDL structure you want to process.

For example, for an IDL structure defined as follows:

s = {ASTRUCTURE,zero:0B,one:0L,two:0.0,three:0D,four: intarr(2)}  

the corresponding C structure would look like the following:

typedef struct {  
   unsigned char zero;  
   IDL_LONG one;  
   float two;  
   double three;  
   short four[2];  
} ASTRUCTURE;  

Then, cast the pointer from argv to the structure type, as follows:

ASTRUCTURE* mystructure;  
mystructure = (ASTRUCTURE*) argv[0];  

The following routine, found in incr_struct.c, increments each field of an IDL structure of type ASTRUCTURE. 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:

Table 3-5: Accessing an IDL Structure from a C Routine — incr_struct.c

Table 3-5: Accessing an IDL Structure from a C Routine — incr_struct.c
C
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
#include <stdio.h>  
#include "idl_export.h"   
   
/*  
 * C definition for the structure that this routine accepts.The  
 * corresponding IDL structure definition would look like this:  
 *     s = {zero:0B,one:0L,two:0.,three:0D,four: intarr(2)}  
*/  
typedef struct {  
  unsigned char zero;  
  IDL_LONG one;  
  float two;  
  double three;  
  short four[2];  
} ASTRUCTURE;  
   
int incr_struct_natural(ASTRUCTURE *mystructure, IDL_LONG n)  
{  
  /* for each structure in the array, increment every field */  
  for (; n--; mystructure++) {  
    mystructure->zero++;  
    mystructure->one++;  
    mystructure->two++;  
    mystructure->three++;  
    mystructure->four[0]++;  
    mystructure->four[1]++;  
  }  
    
  return 1;  
}  
int incr_struct(int argc, void *argv[])  
{  
  if (argc != 2) return 0;  
  return incr_struct_natural((ASTRUCTURE*) argv[0], (IDL_LONG) 
argv[1]);  
}  

It is not possible to access structures with arbitrary definitions using the CALL_EXTERNAL interface. The system routine interface, discussed in Adding System Routines, does provide support for determining the layout of a structure at runtime.

  IDL Online Help (March 06, 2007)