SAS 9.1 Companion For Unix Enivronments

Introduction to the SASCBTBL Attribute Table

Because the MODULE function invokes an external routine that SAS knows nothing about, you must supply information about the routine's arguments so that the MODULE function can validate them and convert them, if necessary. For example, suppose you want to invoke a routine that requires an integer as an argument. Because SAS uses floating point values for all of its numeric arguments, the floating point value must be converted to an integer before you invoke the external routine. The MODULE function looks for this attribute information in an attribute table that is referred to by the SASCBTBL fileref.

What is the SASCBTBL Attribute Table?

The attribute table is a sequential text file that contains descriptions of the routines you can invoke with the MODULE function. The table defines how the MODULE function should interpret supplied arguments when it builds a parameter list to pass to the called routine.

The MODULE function locates the table by opening the file that is referenced by the SASCBTBL fileref. If you do not define this fileref, the MODULE function simply calls the requested shared library routine without altering the arguments.

Caution  

Using the MODULE function without defining an attribute table can cause SAS to crash, produce unexpected results, or result in severe errors. You need to use an attribute table for all external functions that you want to invoke.

Syntax of the Attribute Table

The attribute table should contain the following:

At any point in the attribute table file, you can create a comment using an asterisk (*) as the first nonblank character of a line or after the end of a statement (following the semicolon). You must end the comment with a semicolon.

ROUTINE Statement

The syntax of the ROUTINE statement is

ROUTINE name MINARG= minarg MAXARG= maxarg

The following are descriptions of the ROUTINE statement attributes:

ROUTINE name

MINARG= minarg

MAXARG= maxarg

CALLSEQ=BYVALUE BYADDR

TRANSPOSE=YES NO

MODULE= shared-library-name

RETURNS=SHORT USHORT LONG ULONG DOUBLE DBLPTR CHAR< n >

ARG Statement

The ROUTINE statement must be followed by as many ARG statements as you specified in the MAXARG= option. The ARG statements must appear in the order that the arguments will be specified within the MODULE function.

The syntax for each ARG statement is

ARG argnum NUMCHAR <INPUTOUTPUTUPDATE> <NOTREQDREQUIRED> <BYADDRBYVALUE> <FDSTART> <FORMAT= format >;

Here are the descriptions of the ARG statement attributes:

ARG argnum

NUM CHAR

INPUT OUTPUT UPDATE

NOTREQD REQUIRED

BYADDR BYVALUE

FDSTART

FORMAT= format

The Importance of the Attribute Table

The MODULE function relies heavily on the accuracy of the information in the attribute table. If this information is incorrect, unpredictable results can occur (including a system crash).

Consider an example routine xyz that expects two arguments: an integer and a pointer. The integer is a code indicating what action takes place. For example, action 1 means that a 20-byte character string is written into the area that is pointed to by the second argument, the pointer.

Now suppose you call xyz using the MODULE function, but you indicate in the attribute table that the receiving character argument is only 10 characters long:

routine xyz minarg=2 maxarg=2; arg 1 input num byvalue format=ib4.; arg 2 output char format=$char10.;

Regardless of the value given by the LENGTH statement for the second argument to MODULE, MODULE passes a pointer to a 10-byte area to the xyz routine. If xyz writes 20 bytes at that location, the 10 bytes of memory following the string provided by MODULE are overwritten, causing unpredictable results:

data _null_; length x ; call module('xyz',1,x); run;

The call might work fine, depending on which 10 bytes were overwritten. However, this might also cause you to lose data or cause your system to crash.

Also, note that the PEEKLONG and PEEKCLONG functions rely on the validity of the pointers you supply. If the pointers are invalid, it is possible that severe errors will result. For example, this code would cause an error:

data _null_; length c ; /* trying to copy from address 0!!!*/ c = peekclong(0,10); run;

Категории