The "Sub85" Interface

The "sub85" interface can be more useful than the "sub" interface because more information about each USING parameter is passed to the C subroutines. However, using the "sub85" interface also involves more programming.

The "sub85.c" file contains a table called LIBTABLE. This table consists of a variable number of entries. Each entry contains a routine name and the name of the corresponding C subroutine. The last entry in this table must be NULL to mark the end of the table. When a CALL statement executes, this table is searched for a matching routine name. If a match is found, the corresponding routine is executed.

When the routine is called, it is passed four parameters: name, num_args, args, and initial (in that order). The name argument is a character pointer to the name that the CALL statement used to access the subroutine. The num_args parameter is an integer that contains the number of USING arguments specified by the CALL statement.

The args parameter is defined as an array of type Argument. This type (a structure) is declared in "sub.h". For each USING parameter, the corresponding array element contains the following series of fields that describes that parameter:

a_address — a character pointer that points to the first byte of the USING parameter

a_length — a long integer that contains the number of bytes contained in the USING parameter

a_type — a short integer that contains one of the following values depending on the passed data type:

0 Numeric edited
1 Unsigned numeric (DISPLAY)
2 Signed numeric (DISPLAY, trailing separate)
3 Signed numeric (DISPLAY, trailing combined)
4 Signed numeric (DISPLAY, leading separate)
5 Signed numeric (DISPLAY, leading combined)
6 Signed COMP-2
7 Unsigned COMP-2
8 Unsigned COMP-3
9 Signed COMP-3
10 COMP-6
11 Signed binary (COMP-1, COMP-4, COMP-X)
12 Unsigned binary (COMP-1, COMP-4, COMP-X)
13 Signed native (COMP-5, COMP-N, SIGNEDSHORT, SIGNED-INT, SIGNED-LONG)
14 Unsigned native (COMP-5, COMP-N, UNSIGNEDSHORT, UNSIGNED-INT, UNSIGNED-LONG)
15 Floating point (FLOAT, DOUBLE)
16 Alphanumeric
17 Alphanumeric (justified)
18 Alphabetic
19 Alphabetic (justified)
20 Alphanumeric edited
21 Not used
22     Group

Note that setting the u.pass_type member of the Argument structure controls how data is passed back and forth between a program running on the client and a remote COBOL object. Set u.pass_type to "0" to pass data by reference. Use this when the COBOL application is to read and write data to the variable. Use BY REFERENCE for string literals. Set u.pass_type to "1" to pass data by content. Use this when you want to allow read access to the data item, but the COBOL application should not write to the address. Use BY CONTENT for constants. Set u.pass_type to "2" to pass data by value. Use BY VALUE for numbers.

a_digits — a char that contains the total number of digits in a numeric data type. For non-numeric data types, this value is always zero.

a_scale — a char that contains the power of 10 to multiply the number by. This indicates the location of the decimal point. For example, a value of "-1" indicates that there is one digit to the right of the decimal point. Note that since this is defined as a "char", you may not be able to treat this as a signed value on all machines. The macro "Scale" in "sub.h" converts one of these fields to a signed integer in a machine independent manner.

The final argument to the C subroutine, initial, is set to a non-zero value if the routine is being called for the first time. It is also set to a non-zero value for the first call after a CANCEL statement has been executed for the routine. On any other call, initial is set to zero.

The external variable return-code can be set to any value. The COBOL variable RETURN-CODE will have that value when control returns to the COBOL program. By convention, when a C routine finishes it should return zero if everything was okay. Any other positive return value causes a STOP RUN to be executed, and that value is returned to the operating system as the RETURN-CODE for the run. The C routine should never return a negative value.