The following sections describe the methods involved in sharing DEC C program sections with data declared in other OpenVMS languages.
In a FORTRAN program, separately compiled procedures can share data in declared common blocks, which specify the names of one or more variables to be placed in them. Each named common block represents a separate program section. Each procedure that declares the common block with the same name can access the same variable.
Example 3-14 shows a DEC C extern variable that corresponds to a FORTRAN common block with the same name.
C FORTRAN program PRSTRING.FOR contains the following lines of code: SUBROUTINE PRSTRING CHARACTER*20 STRING COMMON /XYZ/ STRING TYPE 20, STRING 20 FORMAT (' ',A20) RETURN END C End of FORTRAN program /* DEC C program STRING.C contains the following lines of * * code: */ main(void) { #pragma extern_model common_block extern char xyz[20]; strncpy(xyz,"This is a string ", sizeof xyz); prstring(); }
In Example 3-14, the DEC C extern variable xyz corresponds to the FORTRAN common block named XYZ. The FORTRAN procedure displays the data in the block. When sharing program sections, both programs should declare corresponding variables to be of the same type.
Note the #pragma extern_model common_block preprocessor directive. This directive sets the model for external variables to the common_ block model, which is the one used by VAX C. The default external model for DEC C is the relaxed_refdef model. For more information on the #pragma extern_model common_block preprocessor directive, see Section 5.4.4.
To share data in more than one variable in a program section with a FORTRAN program, the DEC C variables must be declared within a structure, as shown in Example 3-15.
C FORTRAN program FNUM.FOR contains the following lines of code: SUBROUTINE FNUM INTEGER*4 INUM,JNUM,KNUM COMMON /NUMBERS/ INUM,JNUM,KNUM TYPE 10, (INUM,JNUM,KNUM) 10 FORMAT (318) RETURN END C End of FORTRAN program /* DEC C program NUMBERS.C contains the following lines of * * code: */ struct xs { int first; int second; int third; }; #pragma extern_model common_block main() { extern struct xs numbers; numbers.first = 1; numbers.second = 2; numbers.third = 3; fnum(); }
In Example 3-15, the int variables declared in the DEC C structure numbers correspond to the FORTRAN INTEGER*4 variables in the COMMON of the same name.
Also, note the #pragma extern_model common_block preprocessor directive. This directive sets the model for external variables to the common_block model, which is the one used by VAX C. The default external model for DEC C is the relaxed_refdef model. For more information on the #pragma extern_model common_block preprocessor directive, see Section 5.4.4.
A VAX PL/I variable with the EXTERNAL attribute corresponds to a FORTRAN common block and to a DEC C extern variable in the common_ block external model. Example 3-16 and Example 3-17 show how a program section is shared between DEC C and VAX PL/I.
A PL/I EXTERNAL CHARACTER attribute corresponds to a DEC C extern char variable, but PL/I character strings are not necessarily null- terminated. In Example 3-16, DEC C and VAX PL/I use the same variable to manipulate the character string that resides in a program section named XYZ.
/* PL/I program PRSTRING.PLI contains the following lines of code: */ PRSTRING: PROCEDURE; DECLARE XYZ EXTERNAL CHARACTER(20); PUT SKIP LIST(XYZ); RETURN; END PRSTRING; /* End of PL/I program */ /* DEC C program STRING.C contains the following lines of * * code: */ main(void) { extern char xyz[20]; strncpy(xyz,"This is a string ", sizeof xyz); prstring(); }
The PL/I procedure PRSTRING writes out the contents of the external variable XYZ.
PL/I also has a structure type similar (in its internal representation) to the struct keyword in DEC C. Moreover, VAX PL/I can output aggregates, such as structures and arrays, in fairly simple stream-output statements; consider Example 3-17.
/* PL/I program FNUM.PLI contains the following lines of code: */ FNUM: PROCEDURE; /* EXTERNAL STRUCTURE CONTAINING THREE INTEGERS */ DECLARE 1 NUMBERS EXTERNAL, 2 FIRST FIXED(31), 2 SECOND FIXED(31), 2 THIRD FIXED(31); PUT SKIP LIST('Contents of structure:',NUMBERS); RETURN; END FNUM; /* End of PL/I program */ /* DEC C program NUMBERS.C contains the following lines of * * code: */ struct xs { int first; int second; int third; }; main() { extern struct xs numbers; numbers.first = 1; numbers.second = 2; numbers.third = 3; fnum(); }
The PL/I procedure FNUM writes out the complete contents of the external structure NUMBERS; the structure members are written out in the order of their storage in memory, which is the same as for a DEC C structure.
In a MACRO program, the .PSECT directive sets up a separate program section that can store data or MACRO instructions. The attributes in the .PSECT directive describe the contents of the program section.
Example 3-18 shows how to set up a psect in a MACRO program that allows data to be shared with a DEC C program.
; MACRO source file SET_VALUE.MAR contains the following lines of code: .entry set_value,^M<> movl #1,first movl #2,second movl #3,third ret .psect example pic,usr,ovr,rel,gbl,noshr,- noexe,rd,wrt,novec,long first: .blkl second: .blkl third: .blkl .end ; End of MACRO source file /* DEC C program NUMBERS.C contains the following lines of * * code: */ #pragma extern_model common_block struct xs { int first; int second; int third; } example; main() { set_value(); printf("example.first = %d\n", example.first); printf("example.second = %d\n", example.second); printf("example.third = %d\n", example.third); }
The MACRO program initializes the locations first, second, and third in the psect named example and passes these values to the DEC C program. The locations are referenced in the DEC C program as members of the external structure named example.
Also, note the #pragma extern_model common_block preprocessor directive. This directive sets the model for external variables to the common_block model, which is the one used by VAX C. The default external model for DEC C is the relaxed_refdef model. For more information on the #pragma extern_model common_block preprocessor directive, see Section 5.4.4.