Previous External Development Guide: Using CALL_EXTERNAL Next

Passing String Data

IDL represents strings internally as IDL_STRING descriptors. For more information about IDL_STRING, see IDL Internals: Variables and IDL Internals: String Processing. These descriptors are defined in the C language as:

typedef struct {  
  IDL_STRING_SLEN_T slen;  
  unsigned short stype;  
  char *s;  
} IDL_STRING;  

To pass a string by reference, IDL passes the address of its IDL_STRING descriptor. To pass a string by value the string pointer (the s field of the descriptor) is passed. Programmers should be aware of the following when manipulating IDL strings:

Returning a String Value

When returning a string value, a function must allocate the memory used to hold it. On return, IDL will copy this string. You can use a static buffer or dynamic memory, but do not return the address of an automatic (stack-based) variable.


Note
IDL will not free dynamically-allocated memory for this use.

Example

The following routine, found in string_array.c, demonstrates how to handle string variables in external code. This routine takes a string or array of strings as input and returns a copy of the longest string that it received. It is important to note that this routine uses a static char array as its return value, which avoids the possibility of a memory leak, but which must be long enough to handle the longest string required by the application. 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:

  

Figure 3-1: Handling String Variables in External Code — string_array.c 

Figure 3-1: Handling String Variables in External Code — string_array.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  
37  
38  
39  
40  
41  
#include <stdio.h>  
#include <string.h>  
#include "idl_export.h"  
/*  
 * IDL_STRING is declared in idl_export.h like this:  
 *   typedef struct {  
 *   IDL_STRING_SLEN_T slen;        Length of string, 0 for null  
 *   short stype;                   Type of string, static or dynamic  
 *   char *s;                       Address of string  
 * } IDL_STRING;  
 * However, you should rely on the definition in idl_export.h instead  
 * of declaring your own string structure.  
*/  
   
char* string_array_natural(IDL_STRING *str_descr, IDL_LONG n)  
{  
  /*  
  * IDL will make a copy of the string that is returned (if it is   
  * not NULL). One way to avoid a memory leak is therefore to return   
  * a pointer to a static buffer containing a null terminated string.  
  * IDL will copy the contents of the buffer and drop the reference  
  * to our buffer immediately on return.  
  */  
#define MAX_OUT_LEN 511                 /* truncate any string   
                                           longer than this */  
  static char result[MAX_OUT_LEN+1];   /* leave a space for a '\0'   
                                          on the longest string */  
  int max_index;                /* index of longest string */  
  int max_sofar;                /* length of longest string*/  
  int i;  
   
  /*  Check the size of the array passed in. n should be > 0.*/  
  if (n < 1) return (char *) 0;  
  max_index = 0;  
  max_sofar = 0;  
  for(i=0; i < n; i++) {  
    if (str_descr[i].slen > max_sofar) {  
      max_index = i;  
      max_sofar = str_descr[i].slen;  
    }  
  }  
C
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
 /*  
  * If all strings in the array are empty, the longest  
  * will still be a NULL string.  
  */  
  if (str_descr[max_index].s == NULL) return (char *) 0;  
   
  /*  
  * Copy the longest string into the buffer, up to MAX_OUT_LEN  
  * characters.  
  * Explicitly store a NULL byte in the last byte of the buffer,  
  * because strncpy() does not NULL terminate if the string copied  
  * is truncated.  
  */  
  strncpy(result, str_descr[max_index].s, MAX_OUT_LEN);  
  result[sizeof(result)-1] = '\0';  
  return(result);  
#undef MAX_OUT_LEN  
}  
   
char* string_array(int argc, void* argv[])  
{  
  /*  
  * Make sure there are the correct  # of arguments.  
  * IDL will convert the NULL into an empty string ('').  
  */  
  if (argc != 2) return (char *) NULL;  
  return string_array_natural((IDL_STRING *) argv[0], (IDL_LONG) argv[1]);  
}  
  

  IDL Online Help (March 06, 2007)