HP OpenVMS Systems Documentation

Content starts here

HP BASIC for OpenVMS
User Manual


Previous Contents Index

18.4 Network I/O

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:

  • Read and write files on a remote node as you do files on your own system (remote file access)
  • Exchange data with a process executing at a remote location (task-to-task communication)

18.4.1 Remote File Access

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.

Note

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:

  1. Establish a command file at the remote site to execute the program you want. The program must be in executable image format. For example, you can create the file MARG.COM at the remote site. MARG.COM contains a line to run an image (in this case, COPYT.EXE).


    $ RUN COPYT
    

    The OPEN statements in the programs at both nodes must specify the same file attributes.
  2. Start task-to-task communication by accessing the command file at the remote site. For example, a program at the local node could contain the following line:


    OPEN 'WESTON::"TASK = MARG"' AS FILE #1%, SEQUENTIAL
    
  3. The system then assigns the logical name SYS$NET to the program at the local node. At the remote node, the program (COPYT.EXE) must use this logical for all operations. For example:


    OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL
    
  4. The two programs can then exchange messages. The programs must have a complementary series of send/receive statements.


!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.


Chapter 19
Using BASIC in the Common Language Environment

This chapter shows you how to call the following:

  • External routines written in other OpenVMS languages
  • OpenVMS Run-Time Library routines
  • OpenVMS system services

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:

  • By reference---BY REF
  • By descriptor---BY DESC
  • By value---BY VALUE

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:

  • Character strings
  • Arrays
  • Compound data structures

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.

Table 19-1 Valid Parameter-Passing Mechanisms
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

1Specifies the default parameter-passing mechanism.

19.1.5 Creating Local Copies

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

Output


 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

Output


 3

19.1.6 Passing Arrays

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:

  • The name of the external routine
  • The data types of all the routine parameters
  • The passing mechanisms for all the routine parameters, provided that the routine is not written in HP BASIC

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