home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Id: string_array.c,v 1.2 1995/08/07 19:28:01 kirk Exp $
- **
- ** NAME:
- ** string_array
- **
- ** PURPOSE:
- ** This C function is used to demonstrate how to pass a IDL array
- ** of type string to a C function using the IDL function CALL_EXTERNAL.
- **
- ** CATEGORY:
- **
- ** Dynamic Link
- **
- ** CALLING SEQUENCE:
- ** This function is called in IDL by using the following command
- **
- ** IDL> result = CALL_EXTERNAL('string_array.so', '_string_array', $
- ** IDL> array_var, array_size)
- **
- ** INPUTS:
- **
- ** array_var: A IDL array of type string
- **
- ** array_size: A IDL scalar long varaible that contains the number
- ** of elements in array_var. This is the number that
- ** is returned from the IDL function N_ELEMENTS.
- **
- ** OUTPUTS:
- ** This function will return the lexical maximum value of the passed in
- ** array. This value is an IDL string scalar value.
- **
- ** SIDE EFFECTS:
- ** The values contained in the array and the number of elements
- ** are written to stdout.
- **
- ** RESTRICTIONS:
- ** This example assumes that the length value is long (4 bytes) and not
- ** a short integer. An IDL integer is only 2 bytes long, so the variables
- ** should be delcared in IDL at type long.
- **
- ** The values contained in the IDL STRING structures should NOT be
- ** changed. If the string structures are changed, IDL will not
- ** know the correct amount of memory allocated to the string and
- ** errors could arise. To manipulate strings the user should
- ** copy the STRING->s field to another variable and perform the
- ** desired string operations. To return a string value to IDL, the
- ** user should return the value through the C function return value and
- ** use the /S_VALUE keyword with CALL_EXTERNAL.
- **
- ** EXAMPLE:
- **-----------------------------------------------------------------------------
- ;; The following are the commands that would be used to call this
- ;; routine in IDL.
- ;;
- array_var = ["AAA","BBB","CCC","DDD","aaa","bbb","ccc","ddd"]
- array_size = n_elements(array_var)
-
- max = CALL_EXTERNAL('string_array.so', '_string_array', $
- array_var, array_size, /S_VALUE )
-
- **-----------------------------------------------------------------------------
- **
- ** MODIFICATION HISTORY:
- ** Written October, 1993 KDB
- **
- ** Declare header file.
- */
-
- #include <stdio.h>
- #include <string.h>
-
- /*
- ** Declare the IDL string Structure. This is take from the IDL header
- ** file $IDL_DIR/source/export.h
- */
- typedef struct {
- unsigned short slen;
- short stype;
- char *s;
- } STRING;
-
- /*
- ** Declare the function
- */
-
- char *
- string_array(argc, argv)
- int argc;
- void *argv[];
- {
- /*
- ** Declare local variables
- */
- char **string_array; /* pointer to a C string array */
- short n_elements; /* number of elements in array */
- char *max_value; /* used to hold max value */
- STRING *str_descr; /* Pointer to array of STRINGs */
- short i; /* Counter */
- long max_index; /* Array Index of max string */
-
- /*
- ** Insure that the correct number of arguments were passed in (argc = 2).
- */
- if(argc != 2)
- {
- /*
- ** Print an error message and return.
- */
- fprintf(stderr, "string_array: Incorrect number of arguments\r\n");
- return((char *)NULL);
- }
- /*
- ** Cast the pointers in argv to local variables.
- */
- str_descr = (STRING *) argv[0];
- n_elements = (short)(*(long*) argv[1]); /* convert long to short */
- /* Needed for an alpha */
- /*
- ** Check the size of the array passed in. n_elements should be > 0.
- */
- if( n_elements < 1)
- {
- /*
- ** Print an error message and return
- */
- fprintf(stderr, "string_array: Array elements is less that one\r\n");
- return((char*)NULL);
- }
-
- /*
- ** First create an actual C string array and copy in the string values
- ** contained in the IDL STRING array
- **
- ** malloc a char* array that contains the same number of elements as
- ** the IDL array.
- */
- if( (string_array=(char**)malloc((unsigned)sizeof(char*)*(n_elements)))
- == (char**)NULL)
- {
- /*
- ** Had a malloc error. Issue an error message and return a NULL
- */
- fprintf(stderr, "string_array: malloc error\r\n");
- return((char*)NULL);
- }
-
- /*
- ** Use a for loop to insert the string elements. Space is malloced for
- ** each element and the IDL string value copied in.
- */
- for(i=0; i < n_elements; i++, str_descr++)
- {
- /*
- ** Allocate memory space for the IDL string value and place the pointer
- ** into the C character string array.
- */
- if( (string_array[i]=(char*)malloc((unsigned)sizeof(char)*
- (str_descr->slen)+1) ) == (char*)NULL )
- {
- /*
- ** We had a malloc error. Free memory, write a message
- ** and return a NULL
- */
- for(--i; i >= 0; i--)
- free( string_array[i] ); /* frees each element */
-
- free((char*)string_array); /* Frees the array of char* */
-
- fprintf(stderr,"string_array: malloc error\r\n");
-
- return( (char*)NULL ); /* Return NULL */
-
- }
-
- /*
- ** Copy the IDL string value into the malloced space
- */
- string_array[i] = strcpy(string_array[i], str_descr->s);
-
- } /* end of build array for loop */
-
- /*
- ** Now we have a C string array. Print out the passed in information
- */
- fprintf(stdout,
- "\r\n-----------------------------------------------------\r\n");
- fprintf(stdout,"Inside C function string_array ");
- fprintf(stdout,"(Called from IDL using CALL_EXTERNAL)\r\n\r\n");
-
- /*
- ** Now print the values of each variable that was passed in from IDL
- */
- fprintf(stdout,"Number of elements in the String array: %d\r\n",n_elements);
- fprintf(stdout, "String Array Contents:\r\n");
-
- for(i=0; i < n_elements; i++)
- fprintf(stdout,"\tElement %3d: %s\r\n",i, string_array[i]);
-
- fprintf(stdout,
- "\r\n-----------------------------------------------------\r\n");
-
- /*
- ** Now we have C string (char **) array that contains the values
- ** of the IDL STRING structures. Now find the Max valued string.
- */
- for(max_index=0, i=1; i < n_elements; i++)
- /*
- ** Compair the max and the current string values
- */
- if(strcmp( string_array[max_index], string_array[i] ) < 0 )
- max_index = i;
- /*
- ** Now malloc space for the max string and copy it to the max_sting
- ** pointer.
- */
- if( (max_value=(char*)malloc((unsigned)sizeof(char)*strlen(string_array[max_index])))
- == (char*)NULL )
- /*
- ** We had a malloc error, write a message and skip the rest of the
- ** function
- */
- fprintf(stderr,"string_array: malloc error\r\n");
- else
- /*
- ** Copy the max string into the max_value pointer.
- */
- max_value = strcpy(max_value, string_array[max_index] );
-
- /*
- ** free all the allocated memory except for the max_value and return
- ** max_value to IDL
- */
- for(i=0; i < n_elements; i++)
- free(string_array[i]);
-
- free( (char*)string_array );
-
- return( max_value );
-
- } /* end of string array */
-
-
-
-
-
-