Compaq C
Compaq C User's Guide for OpenVMS Systems
3.4.2 Sharing Program Sections with PL/I Externals
A Compaq PL/I variable with the EXTERNAL attribute corresponds to a
FORTRAN common block and to a Compaq C
extern
variable in the
common_block
external model. Example 3-16 and Example 3-17 show
how a program section is shared between Compaq C and Compaq PL/I.
A PL/I EXTERNAL CHARACTER attribute corresponds to a Compaq C
extern char
variable, but PL/I character strings are not necessarily
null-terminated. In Example 3-16, Compaq C and Compaq PL/I use
the same variable to manipulate the character string that resides in a
program section named XYZ.
Example 3-16 Sharing Data with a PL/I Program
in Named Program Sections |
/* 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 */
/* Compaq 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 Compaq C. Moreover, Compaq PL/I can output
aggregates, such as structures and arrays, in fairly simple
stream-output statements; consider Example 3-17.
Example 3-17 Sharing Data with a PL/I Program
in a Compaq C Structure |
/* 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 */
/* Compaq 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
Compaq C structure.
3.4.3 Sharing Program Sections with MACRO Programs
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 Compaq C program.
Example 3-18 Sharing Data with a MACRO
Program in a Compaq C Structure |
; 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
/* Compaq 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 Compaq C program. The locations are
referenced in the Compaq 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
Compaq C is the
relaxed_refdef
model. For more information on the
#pragma extern_model common_block
preprocessor directive, see Section 5.4.5.
3.5 OpenVMS Run-Time Library Routines
The OpenVMS Run-Time Library (RTL) is a library of prewritten,
commonly used routines that perform a wide variety of functions. These
routines are grouped according to the types of tasks they perform, and
each group has a prefix that identifies those routines as members of a
particular OpenVMS RTL facility. Table 3-10 lists all the
language-independent, run-time library facility prefixes and the types
of tasks each facility performs.
Table 3-10 OpenVMS Run-Time Library Facilities
Facility Prefix |
Types of Tasks Performed |
DTK$
|
DECtalk routines that are used to control the Compaq DECtalk device.
|
LIB$
|
Library routines that obtain records from devices, manipulate strings,
convert data types for I/O, allocate resources, obtain system
information, signal exceptions, establish condition handlers, enable
detection of hardware exceptions, and process cross-reference data.
|
MTH$
|
Mathematics routines that perform arithmetic, algebraic, and
trigonometric calculations.
|
OTS$
|
General-purpose routines that perform tasks such as data-type
conversions as part of a compiler's generated code.
|
SMG$
|
Screen management routines that are used in designing, composing, and
keeping track of complex images on a video screen.
|
STR$
|
String manipulation routines that perform such tasks as searching for
substrings, concatenating strings, and prefixing and appending strings.
|
The OpenVMS run-time library routines are documented in detail
in the following operating system documentation:
- OpenVMS RTL DECtalk (DTK$) Manual
- OpenVMS RTL Library (LIB$) Manual
- OpenVMS VAX RTL Mathematics (MTH$) Manual
- Compaq Portable Mathematics Library
- OpenVMS RTL General Purpose (OTS$) Manual
- OpenVMS RTL Screen Management (SMG$) Manual
- OpenVMS RTL String Manipulation (STR$) Manual
3.6 OpenVMS System Services Routines
System services are prewritten system routines that perform a variety
of tasks, such as controlling processes, communicating among processes,
and coordinating I/O.
Unlike the OpenVMS Run-Time Library (RTL) routines, which are
divided into groups by facility, all system services share the same
facility prefix (SYS$). However, these services are logically divided
into groups that perform similar tasks. Table 3-11 describes these
groups.
Table 3-11 OpenVMS System Services
Group |
Types of Tasks Performed |
AST
|
Allows processes to control the handling of asynchronous system traps
(ASTs).
|
Change mode
|
Changes the access mode of particular routines.
|
Condition handling
|
Designates condition handlers for special purposes.
|
Event flag
|
Clears, sets, reads, and waits for event flags, and associates with
event flag clusters.
|
Information
|
Returns information about the system, queues, jobs, processes, locks,
and devices.
|
Input/Output
|
Performs I/O directly without going through RMS.
|
Lock management
|
Enables processes to coordinate access to shareable system resources.
|
Logical names
|
Provides methods of accessing and maintaining pairs of character-string
logical names and equivalence names.
|
Memory management
|
Increases or decreases available virtual memory, controls paging and
swapping, and creates and accesses shareable files of code or data.
|
Process control
|
Creates, deletes, and controls execution of processes.
|
Security
|
Enhances the security of
OpenVMS systems.
|
Time and Timing
|
Schedules events and obtains and formats binary time values.
|
System services are documented in detail in the OpenVMS System Services Reference Manual.
The routines that provide a programming interface to various OpenVMS
utilities are described in the OpenVMS Utility Routines Manual.
3.7 Calling Routines
The basic steps for calling routines are the same whether you are
calling a routine written in Compaq C, a routine written in some
other OpenVMS language, a system service, or an
OpenVMS Run-Time Library (RTL) routine. The following sections
outline the procedures for calling non-Compaq C routines.
3.7.1 Determining the Type of Call
Before calling an external routine, you must first determine whether
the call should be a procedure call or a function call. Call a routine
as a procedure if it does not return a value. Call a routine as a
function if it returns any type of value.
3.7.2 Declaring an External Routine and Its Arguments
To call an external routine or system routine, you need to declare it
as an external function and to declare the names, data types, and
passing mechanisms of its arguments. Arguments can be either required
or optional.
Include the following information in a routine declaration:
- The name of the external routine
- The data types of all the routine parameters (optional)
- The data type of the return value if it is a function
- The
void
keyword if it is a procedure
The following example shows how to declare an external routine and its
arguments:
char func_name (int x, char y);
|
Header files are available to declare commonly used external routines.
Using them will save you a lot of work. See Sections 1.3.1.1 and
1.3.1.2 in this manual for information on listing and including
header files.
3.7.3 Calling the External Routine
After declaring an external routine, you can invoke it. To invoke a
function, you must specify the name of the routine being invoked and
all arguments required for that routine. Make sure the data types for
the actual arguments you are passing coincide with those of the
parameters you declared earlier, and with those declared in the
routine. The following example shows how to invoke the function
declared in Section 3.7.2:
ret_status = func_name(1,'a');
|
3.7.4 System Routine Arguments
All system routine arguments are described in terms of the following
information:
- OpenVMS usage
- Data type
- Type of access allowed
- Passing mechanism
OpenVMS usages are data structures that are layered on the
standard OpenVMS data types. For example, the OpenVMS
usage mask_longword signifies an unsigned longword integer that is used
as a bit mask, and the OpenVMS usage floating_point represents
any OpenVMS floating-point data type. Table 3-12 lists all
the OpenVMS usages and the Compaq C types you need to
implement them.
Table 3-12 Compaq C Implementation
OpenVMS Data Type |
Compaq C Declaration |
access_bit_names
|
user-defined
1
|
access_mode
|
unsigned char
|
address
|
int *pointer
2,4
|
address_range
|
int *array [2]
2,3,4
|
arg_list
|
user-defined
1
|
ast_procedure
|
pointer to a function
2
|
boolean
|
unsigned long int
|
byte_signed
|
char
|
byte_unsigned
|
unsigned char
|
channel
|
unsigned short int
|
char_string
|
char array[n]
3,5
|
complex_number
|
user-defined
1
|
cond_value
|
unsigned long int
|
context
|
unsigned long int
|
date_time
|
user-defined
1
|
device_name
|
char array[n]
3,5
|
ef_cluster_name
|
char array[n]
3,5
|
ef_number
|
unsigned long int
|
exit_handler_block
|
user-defined
1
|
fab
|
#include fab from text library
struct FAB
|
file_protection
|
unsigned short int, or user-defined
1
|
floating_point
|
float or double
|
function_code
|
unsigned long int or user-defined
1
|
identifier
|
int *pointer
2,4
|
io_status_block
|
user-defined
1
|
item_list_2
|
user-defined
1
|
item_list_3
|
user-defined
1
|
item_list_pair
|
user-defined
1
|
item_quota_list
|
user-defined
1
|
lock_id
|
unsigned long int
|
lock_status_block
|
user-defined
1
|
lock_value_block
|
user-defined
1
|
logical_name
|
char array[n]
3,5
|
longword_signed
|
long int
|
longword_unsigned
|
unsigned long int
|
mask_byte
|
unsigned char
|
mask_longword
|
unsigned long int
|
mask_quadword
|
user-defined
1
|
mask_word
|
unsigned short int
|
null_arg
|
unsigned long int
|
octaword_signed
|
user-defined
1
|
octaword_unsigned
|
user-defined
1
|
page_protection
|
unsigned long int
|
procedure
|
pointer to function
2
|
process_id
|
unsigned long int
|
process_name
|
char array[n]
3,5
|
quadword_signed
|
user-defined
1
|
quadword_unsigned
|
user-defined
1
|
rights_holder
|
user-defined
1
|
rights_id
|
unsigned long int
|
rab
|
#include rab
struct RAB
|
section_id
|
user-defined
1
|
section_name
|
char array[n]
3,5
|
system_access_id
|
user-defined
1
|
time_name
|
char array[n]
3,5
|
uic
|
unsigned long int
|
user_arg
|
user-defined
1
|
varying_arg
|
user-defined
1
|
vector_byte_signed
|
char array[n]
3,5
|
vector_byte_unsigned
|
unsigned char array[n]
3,5
|
vector_longword_signed
|
long int array[n]
3,5
|
vector_longword_unsigned
|
unsigned long int array[n]
3,5
|
vector_quadword_signed
|
user-defined
1
|
vector_quadword_unsigned
|
user-defined
1
|
vector_word_signed
|
short int array[n]
3,5
|
vector_word_unsigned
|
unsigned short int array[n]
3,5
|
word_signed
|
short int
|
word_unsigned
|
unsigned short int
|
1The declaration of a user-defined data structure depends on
how the data will be used. Such data structures can be declared in a
variety of ways, each of which is more suitable to specific
applications.
2The term pointer refers to several declarations involving
pointers. Pointers are declared with special syntax and are associated
with the data type of the object being pointed to. This object is often
user-defined.
3The term array denotes the syntax of a Compaq C array
declaration.
4The data type specified can be changed to any valid
Compaq C data type.
5The size of the array must be substituted for n.
If a system routine argument is optional, it will be indicated in the
format section of the routine description in one of two ways, as
follows:
- [,optional-argument]
- ,[optional-argument]
If the comma appears outside the brackets, you must pass a 0 by value
to indicate the place of the omitted argument. If the comma appears
inside the brackets, you can omit the argument if it is the last
argument in the list.
For more information, see the OpenVMS Programming Interfaces:
Calling a System Routine manual. This manual describes the OpenVMS
programming interface and defines the standard conventions to call an
OpenVMS system routine from a user procedure. The Alpha and VAX data
type implementations for various high-level languages are also
presented.
|
|