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

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.