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.