HP OpenVMS Systems Documentation |
HP BASIC for OpenVMS
|
Previous | Contents | Index |
If your system supports DECnet for OpenVMS VAX facilities, and your computer is one of the nodes in a DECnet for OpenVMS VAX, you can communicate with other nodes in the network with HP BASIC program statements. HP BASIC lets you do the following:
To write or read files at a remote site, include the node name as part of the file specification. For example:
OPEN "WESTON::DUA1:[HOLT]TEST.DAT;2" FOR INPUT AS FILE #2% |
You can also assign a logical name to the file specification, and use that logical name in all file I/O.
You need NETMBX privileges to access files at a remote node. |
If the account at the remote site requires a username and password, include this access string in the file specification. You do this by enclosing the access string in quotation marks and placing it between the node name and the double colon. The following file specification accesses the account [HOLT.TMP] on node WESTON by giving the username HOLT and the password PASWRD. After accessing the file, your HP BASIC program can read and write records as if the file were in your account.
OPEN 'WESTON"HOLT PASWRD"::DUA0:[HOLT.TMP]INDEXU.DAT;4' & FOR INPUT AS FILE #1%, INDEXED, PRIMARY TEXT$ |
Do not use the CONNECT clause when opening a file on a remote node or
HP BASIC will signal the error "Cannot open file"
(ERR=162).
18.4.2 Task-to-Task Communication
HP BASIC supports task-to-task communication if your account has NETMBX privileges.
Follow these steps for task-to-task communication:
$ RUN COPYT |
OPEN 'WESTON::"TASK = MARG"' AS FILE #1%, SEQUENTIAL |
OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL |
!Local Program MAP (SJK) MSG$ = 32% OPEN 'WESTON"DAVIS PSWRD"::"TASK = MARG"' & FOR OUTPUT AS FILE #1%, SEQUENTIAL, MAP SJK LINPUT "WHAT IS THE CUSTOMER NAME"; MSG$ PUT #1% GET #1% PRINT MSG$ CLOSE #1% END |
!Remote Node Program . . . 10 MAP (SJK) MSG$ = 32% MAP (FIL) NAME$ = 32%, RESERVATION$ = 64% OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL, & MAP SJK OPEN 'RESER.DAT'FOR INPUT AS FILE #2%, & INDEXED FIXED, PRIMARY NAME$, MAP FIL GET #1% MSG$ = "NAME CONFIRMED" WHEN ERROR IN 100 FIND #2%, KEY 0% EQ MSG$ USE IF ERR = 153 THEN MSG$ = "ERROR IN NAME" ELSE EXIT HANDLER END IF END WHEN PUT #1% . . . CLOSE #2%, 1% END |
The task-to-task communication ends when the files are closed.
See the DECnet for OpenVMS Networking Manual and the HP OpenVMS System Manager's Manual for more information.
18.4.3 Accessing a VAX Rdb/VMS Database
If you have purchased a VAX Rdb/VMS development license, you can store and access data in a VAX Rdb/VMS database from a HP BASIC program. To do this, you embed RDO statements in your HP BASIC program. Each line of an RDO statement must be preceded by the Rdb/VMS statement flag (&RDB&). HP BASIC line numbers cannot be included in any RDO statement line. You then precompile your program with the Rdb/VMS precompiler. The precompiler translates the RDO statements into BASIC statements that make direct calls to Rdb/VMS.
This chapter shows you how to call the following:
The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name), and may or may not have an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, while a function is a routine that returns a value by assigning that value to the function's identifier.
System routines are prewritten OpenVMS routines that
perform common tasks such as finding the square root of a number or
allocating virtual memory. You can call any system routine from
HP BASIC provided that the data structures necessary for that
routine are supported. The system routines used most often are OpenVMS
Run-Time Library routines and system services. System routines, which
are discussed later in this chapter, are documented in detail in the
OpenVMS Run-Time Library Routines Volume and the HP OpenVMS System Services Reference Manual.
19.1 Specifying Parameter-Passing Mechanisms
When you pass data between routines that are not written in the same language, you have to specify how you want that data to be represented and interpreted. You do this by specifying a parameter-passing mechanism. The general parameter-passing mechanisms and their keywords in HP BASIC are as follows:
The following sections outline each of these parameter-passing
mechanisms in more detail.
19.1.1 Passing Parameters by Reference
When you pass a parameter by reference, HP BASIC passes the
address at which the actual parameter value is stored. In other words,
your routine has access to the parameter's storage address; therefore,
you can manipulate and change the value of this parameter. Any changes
that you make to the value of the parameter in your routine are
reflected in the calling routine as well.
19.1.2 Passing Parameters by Descriptor
A descriptor is a data structure that contains the address of a parameter, along with other information such as the parameter's data type and size. When you pass a parameter by descriptor, the HP BASIC compiler passes the address of a descriptor to the called routine. You usually use descriptors to pass parameters that have unknown lengths, such as the following:
Like parameters passed by reference, any change made to the value of a
parameter passed by descriptor is reflected in the calling routine.
19.1.3 Passing Parameters by Value
When you pass a parameter by value, you pass a copy of the parameter value to the routine instead of passing its address. Because the actual value of the parameter is passed, the routine does not have access to the storage location of the parameter; therefore, any changes that you make to the parameter value in the routine do not affect the value of that parameter in the calling routine.
HP BASIC allows actual and formal parameters to be passed by value.
19.1.4 HP BASIC Default Parameter-Passing Mechanisms
There are default parameter-passing mechanisms established for every data type you can use with HP BASIC. Table 19-1 shows which HP BASIC data types you can use with each parameter-passing mechanism.
Parameter | BY VALUE | BY REF | BY DESC |
---|---|---|---|
Integer and Real Data | |||
Variables | Yes | Yes 1 | Yes |
Constants | Yes |
Local
copy 1 |
Local
copy |
Expressions | Yes |
Local
copy 1 |
Local
copy |
Elements of a
nonvirtual array |
Yes | Yes 1 | Yes |
Virtual
array elements |
Yes |
Local
copy 1 |
Local
copy |
Nonvirtual
entire array |
No | Yes | Yes 1 |
Virtual
entire array |
No | No | No |
Packed Decimal Data | |||
Variables | No | Yes 1 | Yes |
Constants | No |
Local
copy 1 |
Local
copy |
Expressions | No |
Local
copy 1 |
Local
copy |
Nonvirtual
array elements |
No | Yes 1 | Yes |
Virtual
array elements |
No |
Local
copy 1 |
Local
copy |
Nonvirtual
entire arrays |
No | Yes | Yes 1 |
Virtual
entire arrays |
No | No | No |
String Data | |||
Variables | No | Yes | Yes 1 |
Constants | No |
Local
copy |
Local
copy 1 |
Expressions | No |
Local
copy |
Local
copy 1 |
Nonvirtual
array elements |
No | Yes | Yes 1 |
Virtual
array elements |
No |
Local
copy |
Local
copy 1 |
Nonvirtual
entire arrays |
No | Yes | Yes 1 |
Virtual
entire arrays |
No | No | No |
Other Parameters | |||
RECORD variables | No | Yes 1 | No |
RFA variables | No | Yes 1 | No |
If a parameter is an expression, function, or virtual array element, then it is not possible to pass the parameter's address. In these cases, HP BASIC makes a local copy of the parameter's value and passes this local copy by reference.
You can force HP BASIC to make a local copy of any parameter by enclosing the parameter in parentheses. Forcing HP BASIC to make a local copy is a useful technique because you make it impossible for the subprogram to modify the actual parameter. In the following example, when variable A is printed in the main program, the value is zero because the variable A is not modifiable by the subprogram:
DECLARE LONG A CALL SUB1 ((A)) PRINT A END SUB SUB1 (LONG B) B = 3 END SUB |
0 |
By removing the extra parentheses from A, you allow the subprogram to modify the parameter.
DECLARE LONG A CALL SUB1 (A) PRINT A END SUB SUB1 (LONG B) B = 3 END SUB |
3 |
In HP BASIC, if a subprogram or function declares an array in its
parameter list, the calling program must pass an array. Passing a null
parameter instead would cause the program to fail with a memory access
violation.
19.2 Calling External Routines
Most of the steps of calling external routines are the same whether you
are calling an external routine written in HP BASIC, an external
routine written in some other language, a system service, or a OpenVMS
Run-Time Library routine. The following sections outline the procedure
for calling non-BASIC external routines. For information about calling
BASIC routines, see Chapter 12.
19.2.1 Determining the Type of Call
Before you call an external routine, you must determine whether the
call to the routine should be a function call or a procedure call. You
should call a routine as a function if it returns any type of value. If
the routine does not return a value, you should call it as a procedure.
19.2.2 Declaring an External Routine and Its Arguments
To call an external routine or system routine you need to declare it as an external procedure or function and to declare the names, data types, and passing mechanisms for the arguments. Arguments can be either required or optional.
You should include the following information in a routine declaration:
When you declare an external routine, use the EXTERNAL statement. This allows you to specify the data types and parameter-passing mechanisms only once.
In the following example, the EXTERNAL statement declares cobsub as an external subprogram with two parameters---a LONG integer and a string both passed by reference:
EXTERNAL SUB cobsub (LONG BY REF, STRING BY REF) |
With the EXTERNAL statement, HP BASIC allows you to specify that particular parameters do not have to conform to specific data types and that all parameters past a certain point are optional. A parameter declared as ANY indicates that any data type can appear in the parameter position. In the following example, the EXTERNAL statement declares a SUB subprogram named allocate. This subprogram has three parameters: one LONG integer, and two that can be of any HP BASIC data type.
EXTERNAL SUB allocate(LONG, ANY,) |
A parameter declared as OPTIONAL indicates that all following parameters are optional. You can have both required and optional parameters. The required parameters, however, must appear before the OPTIONAL keyword because all parameters following it are considered optional.
In the following example, the EXTERNAL statement declares the Run-Time Library routine LIB$LOOKUP_KEY. The keyword OPTIONAL is specified to indicate that the last three parameters can be optional.
EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, STRING, INTEGER) |
For more information about using the EXTERNAL statement, see the
HP BASIC for OpenVMS Reference Manual.
19.2.3 Calling the Routine
Once you have declared an external routine, you can invoke it. To invoke a procedure, you use the CALL statement. To invoke a function, you use the function name in an expression. You must specify the name of the routine being invoked and all parameters required for that routine. Make sure the data types and passing mechanisms for the actual parameters you are passing match those you declared earlier, and those declared in the routine.
If you do not want to specify a value for a required parameter, you can pass a null argument by inserting a comma as a placeholder in the argument list. If you are passing a parameter using a mechanism other than the default passing mechanism for that data type, you must specify the passing mechanism in the CALL statement or the function invocation.
The following example shows you how to call the external subprogram allocate declared in Section 19.2.2. When allocate is called, it is called as a procedure. The first parameter must always be a valid LONG INTEGER value; the second and third parameters can be of any valid HP BASIC data type.
EXTERNAL SUB allocate(LONG, ANY,) . . . CALL allocate (entity%, a$, 1%) |
This next example shows you how to call the Run-Time Library routine LIB$LOOKUP_KEY declared in Section 19.2.2. When the routine LIB$LOOKUP_KEY is called, it is invoked as a function. The first two parameters are required; all remaining parameters are optional.
EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, STRING, INTEGER) . . . ret_status% = LIB$LOOKUP_KEY(value$, point%) |
Note that if the actual parameter's data type in the CALL statement does not match that specified in the EXTERNAL statement, HP BASIC reports the compile-time informational message "Mode for parameter of routine changed to match declaration." This tells you that HP BASIC has made a local copy of the value of the parameter, and that this local copy has the data type specified in the EXTERNAL declaration. HP BASIC warns you of this because the change means that the parameter can no longer be modified by the subprogram. If HP BASIC cannot convert the data type, HP BASIC signals the error "Mode for parameter of routine not as declared."
The routine being called receives control, executes, and then returns control to the calling routine at the next statement after the CALL statement or function invocation.
HP BASIC provides the built-in function LOC to allow you to access the address of a named external function. This is especially useful when passing the address of a callback or AST routine to an external subprogram. In the following example, the address of the function compare is passed to the subprogram come_back_now using the LOC function:
EXTERNAL LONG FUNCTION compare (LONG, LONG) EXTERNAL SUB come_back_now (LONG BY VALUE) CALL come_back_now (LOC(compare) BY VALUE) |
Previous | Next | Contents | Index |