home *** CD-ROM | disk | FTP | other *** search
- The "Extor System."
- Copyright (c) 1988 Nantucket Corp. All rights reserved.
-
-
- Terms:
-
- "Clipper" refers to the Summer87 version of Nantucket's Clipper
- compiler for dBASE. None of this information should be assumed to
- apply to any other version of Clipper.
-
- A "foreign function" is a Clipper-callable function or procedure written
- in a language other than Clipper.
-
- The "Extend System" is the set of functions, header files, etc. supplied
- with Clipper which allow a foreign function to retrieve the values of
- parameters passed from a Clipper program.
-
- The phrase "by reference" refers to a style of parameter passing in
- which a reference to a memory variable is passed instead of the memory
- variable's current value. In Clipper, you achieve this by preceding the
- variable name with the @ character in the function invocation (note
- that this is not necessary for arrays, which are always passed by
- reference).
-
-
-
- Background:
-
- The Extend System is a key element in Clipper's open architecture. It
- allows you to write a foreign function which can be used much as if you
- had written it in Clipper. The function can be written in any language
- which provides a C-compatible calling mechanism. Parameters can be
- retrieved via a set of C-callable "par" functions, and a return value
- can be posted using one of several "ret" functions.
-
- One limitation of the Extend System is that your foreign function can
- return only a single value to the calling program (by posting it with a
- "ret" function) . If a large volume of data is to be supplied or
- processed by a foreign function, you may need to make numerous function
- calls in order to tranfer all of the data. Function calling and
- parameter passing involve significant overhead, so the extra calls may
- degrade performance. (Also they're a pain in the neck.)
-
- If you write your function in Clipper, on the other hand, you can
- directly modify memory variables which were passed by reference. This
- is especially useful with arrays; a single function call can fill an
- array with an arbitrarily large set of values (assuming the passed array
- is large enough to contain them).
-
- The "Extor System" comprises a small set of "stor" functions which allow
- your foreign functions to reassign memory variables which were passed by
- reference from a Clipper program. This includes both individual memory
- variables and array elements.
-
-
-
- Calling Conventions:
-
- The functions follow (sort of) the naming conventions established in the
- "par" functions. In general the form is:
-
- _stor...(value, param_number [, index])
-
- 'value' is the value to be stored to the memory variable. There is
- a different "stor" function for each possible data type.
-
- 'param_number' is the ordinal number (starting with one, like the
- "par" functions) which designates the parameter to be affected.
-
- 'index' (optional) is used to specify which array element you wish
- to store into. It is only meaningful if the designated parameter
- is an array (in which case it is required).
-
-
- This general form is used by the following "stor" functions:
-
- _storc(string, param_number [, index])
-
- Stores a null terminated string to the designated parameter.
-
-
- _storni(int_val, param_number [, index])
-
- Stores an integer numeric value to the designated parameter.
-
-
- _stornl(long_val, param_number [, index])
-
- Stores a long numeric value to the designated parameter.
-
-
- _stornd(double_val, param_number [, index])
-
- Stores a double numeric value to the designated parameter.
-
-
- _storl(int_val, param_number [, index])
-
- Stores a logical value to the designated parameter. The value is
- supplied as an integer. If it is zero, a .F. (FALSE) is stored,
- otherwise a .T. (TRUE) is stored.
-
-
- _stords(date_string, param_number [, index])
-
- Stores a date value to the designated parameter. The value is
- supplied as a null terminated string containing a printable
- representation (in the form YYYYMMDD) of the date to be stored.
- If you supply a string which does not represent a valid date, a
- "blank date" value will be stored to the designated parameter.
-
-
- Two other "stor" functions require an extra argument which specifies
- length information:
-
- _storclen(string, length, param_num [, index])
-
- Stores a string to the designated parameter. The length of the
- string is assumed to be as specified by the 'length' argument
- (an unsigned integer). This allows you to store strings which
- contain embedded null bytes. Note that the supplied string need
- not be null terminated, since this function does not scan for a
- null in order to determine the string's length. The function
- also automatically appends an internal terminator to the stored
- copy of the string. (Nonetheless, it's a good idea to maintain
- null terminators on your strings for consistency.)
-
-
- _storndec(double_val, decimals, param_num [, index])
-
- Stores a double numeric value to the designated parameter. The
- 'decimals' argument specifies the number of decimal places to be
- shown by default when the associated memory variable is displayed.
- Note that this display default has no effect on the actual value of
- the variable; only the display format is affected.
-
-
- All of the functions return an integer. The return value is 1 (TRUE) if
- the function completed successfully, 0 (FALSE) otherwise.
-
-
-
- Notes:
-
- If a designated parameter is not a memory variable passed by reference,
- attempts to "stor" it will be ignored, and the function will return
- FALSE. This means you can safely call these functions on parameters
- that were supposed to have been passed by reference, without checking
- to see that they really were. If you do want to check them, you can
- use the Extend System macro ISBYREF().
-
- If the designated parameter is an array but you fail to supply the
- 'index' argument, the "stor" function will select the element that it
- feels is most appropriate. Just kidding. Actually the results are
- unpredictable, so you should always specify an index if the parameter
- is an array. The Extend System macro ISARRAY() can be used to determine
- whether a particular parameter is an array.
-
- If you try to store an array element which is beyond the limit of the
- associated array, the attempt will be ignored, and the function will
- return FALSE.
-
- It is not possible to create or dimension an array with these functions,
- nor is it possible to change an array to a scalar (non-array).
-
- These functions automatically allocate memory to contain the variable's
- new value. The new value you supply is automatically copied into the
- newly allocated space. If sufficient memory cannot be allocated, the
- variable will remain unchanged and the function will return FALSE. No
- other error is generated.
-
- As with any assignment, the previous contents of the designated memory
- variable are lost if the "stor" function is successful (returns TRUE).
- Any memory that was occupied by the old contents is automatically
- reclaimed.
-
- Future versions of Clipper will likely provide a similar capability. It
- will not necessarily take the same form as this system, however, so you
- would be wise to isolate the use of these functions to easily identified
- areas of your code.
-
-
-
- Example:
-
- /***
- * fill an array with zeros
- *
- * example:
- *
- * PRIVATE a[10]
- * AZERO(a)
- *
- */
-
- CLIPPER AZERO()
-
- {
- int count;
- int index;
-
-
- if (ISARRAY(1))
- {
- count = ALENGTH(1);
- index = 1;
-
- while (index <= count)
- {
- _storni(0, 1, index);
- index++;
- }
- }
-
- _ret();
- }
-
-
-
- Conclusion:
-
- The "Extor System" is a handy thing to have on those occasions when you
- need to retrieve a lot of data from an external source. Other creative
- uses are possible, such as more efficient packing and unpacking of
- structured data.
-
- For some general advice on Clipper-callable functions, please refer to
- the notes in the "readme.doc" file.
-