/*$Id: string_array.c,v 1.1 1998/10/19 20:51:10 beth Exp $ ** ** ** NAME: ** ** string_array.c ** ** PURPOSE: ** This C function is used to demonstrate how to read an array of ** IDL string variables and how to return a string value from a ** CALL_EXTERNAL routine ** ** CATEGORY: ** Dynamic Link ** ** CALLING SEQUENCE: ** This function is called in IDL by using the following commands: ** ** IDL>strarr = ['a','bb','ccc','dddd','ee'] ** IDL>result = CALL_EXTERNAL(library_name,'string_array',strarr,$ ** N_ELEMENTS(strarr),/S_VALUE) ** ** ** See string_array.pro for a more complete calling sequence. ** ** INPUTS: ** string_descr - array of IDL strings (type is IDL_STRING) ** n - number of elements in the array (type is long) ** ** OUTPUTS: ** The function returns the longest string in the array. ** ** SIDE EFFECTS: ** None. ** ** RESTRICTIONS: ** If the longest input string is longer than 511 characters, ** only the first 511 characters will be present in the string ** that is returned. ** ** MODIFICATION HISTORY: ** Written May, 1998 JJG ** */ #include #include "export.h" /* IDL_STRING is declared like this: typedef struct { unsigned short slen; Length of string, 0 for null short stype; type of string, static or dynamic char *s; Addr of string } IDL_STRING; However, you should rely on the definition in export.h instead of declaring your own string structure. */ #include /* make sure that this routine is exported on the Macintosh */ #if defined(__POWERPC__) __declspec(export) char* string_array(int argc,void* argv[]); #endif char* IDL_STDCALL string_array(int argc,void* argv[]) { IDL_STRING *str_descr; IDL_LONG n; /* number of elements in array */ int max_index; /* index of longest string */ int max_sofar; /* length of longest string*/ int i; /* IDL will make a copy of the string that is returned (if it is not NULL). So, to avoid a memory leak the return value should be a pointer to a static buffer containing a null terminated string. */ #define MAX_OUT_LEN 511 /*any string longer than this will be truncated*/ static char result[MAX_OUT_LEN +1]; /*leave a space for a '\0' on the longest string */ /* make sure there are the correct # of arguments. IDL will convert the NULL into an empty string (''). */ if (argc != 2) return((char *)NULL); /* Cast the pointers in argv to local variables. */ str_descr = (IDL_STRING *) argv[0]; n = *(int*) argv[1]; /* Check the size of the array passed in. n should be > 0.*/ if (n < 1) return (char*)NULL; 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; } } /* 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*) NULL; /* copy the longest string into the buffer. Since result was declared static, it will initially be filled with zeros. And, since the buffer is 1 byte longer than MAX_OUT_LEN, the last byte of the buffer should already be a '\0'. This is important, because if the input string to strncpy() is longer than MAX_OUT_LEN, strcpy() will _not_ write a '\0'.*/ strncpy(result,str_descr[max_index].s,MAX_OUT_LEN); return(result); #undef MAX_OUT_LEN }