ACCESS

Top  Previous  Next

 

The ACCESS keyword is used in combination with input parameters to a function to support parameter passing by reference. The standard parameter passing method to a function is by value.

 

This is a simple example of using reference parameter passing:

 

FUNCTION TEST;
VAR_INPUT
   v1 : ACCESS INT;
   v2 : ACCESS STRING;
   v3 : INT;
END_VAR;
   v1 := v1 * 5; 
   v2 := "Hello world";
   v3 := 51;   <--- NOT ALLOWED
END_FUNCTION;
 
VAR
   x1 : INT := 1;
   x2 : INT := 1;
   s  : STRING := "Nice";
END_VAR;

 

Calling the function:

 

TEST( v1 := x1, v2 := s,  v3 := x2 );

 

 

After the call to "test", the contents of the parameters passed to the function are as follows: "x1" is 5, "x2" is 1, and "s" is "Hello world".

Please note that "x2" did not change its value as it was passed by value. "x1" and "s" were both passed by reference and therefore the changes for the actual parameters to "TEST" changed accordingly.

Actually it is not possible for "TEST" to update the "v3" parameter as changes to VAR_INPUT by value parameters in a function are not allowed. Using the ACCESS attribute on a VAR_INPUT variable will, however, change this rule and allow updating of the referenced parameter.

 

By using the ACCESS attribute, it is possible to pass a STRUCT_BLOCK to a function:

 

 

STRUCT_BLOCK server_pack;
   mode         : SINT;
   linsec       : DINT;
   latitude     : DINT;
   longitude    : DINT;
END_STRUCT_BLOCK;
 
 
FUNCTION SendData : BOOL;
VAR_INPUT
   v   : ACCESS server_pack;
   res : ACCESS INT;
END_VAR;
 
   ... Sends the data and returns the status in 'res'.
   res := 0; 
   SendData := TRUE;
    
END_FUNCTION;
 
VAR
   pack : server_pack;
   rc   : INT;
END_VAR;

 

Calling the function to send the "pack" of data:

 

... Fill in the data to send in 'pack', and send.

SendData( v := pack, res := rc );

 

 

Note that any possible changes to the "v" formal parameter in the SendData function will affect the content of the actual parameter "pack".
 

 

STRUCT_BLOCK assignment can be performed through ACCESS parameters. Both referenced variables must have the exact same STRUCT_BLOCK type. The assignment updates the caller-owned destination variable.
 
VAR_INPUT
destination : ACCESS server_pack;
source : ACCESS server_pack;
END_VAR;
 
destination := source;
CopyPack := TRUE;
END_FUNCTION;

 

The ACCESS attribute can also be used with ARRAY parameters in a function VAR_INPUT section. An ACCESS ARRAY parameter gives the function direct access to the caller-owned array storage. The array is not copied, and writes through the formal parameter modify the caller's array elements.

 

FUNCTION SetWindow : INT;
VAR_INPUT
 values : ACCESS ARRAY[2..3] OF INT;
END_VAR;
 
values[2] := 22;
values[3] := 33;
SetWindow := values[2] + values[3];
END_FUNCTION;
 
PROGRAM example;
VAR
 data : ARRAY[0..9] OF INT;
 rc : INT;
END_VAR;
 
rc := SetWindow(values := data);
END_PROGRAM;

 

For ACCESS ARRAY parameters, the actual parameter must be a whole ARRAY variable, a whole ARRAY member selected from a STRUCT_BLOCK, or a row slice from a two-dimensional ARRAY passed to a one-dimensional formal. For example, values := data, values := packet.values, and values := matrix[row] are valid actual parameters. Passing an indexed element, for example values := data[0], values := packet.values[0], or values := matrix[row,column], is not allowed. A normal ARRAY input without ACCESS is not passable by callers; use ACCESS ARRAY when a function must receive an array supplied by the caller.

 

•For one-dimensional ACCESS ARRAY parameters, the actual array may be larger than the formal array when the actual array bounds fully cover the formal bounds. For example, ACCESS ARRAY[10..20] OF INT can receive ARRAY[0..50] OF INT, but ACCESS ARRAY[0..500] OF INT cannot receive ARRAY[0..50] OF INT.

•For a one-dimensional ACCESS ARRAY formal, a row slice from a two-dimensional actual ARRAY may be passed using matrix[row]. The row index may be fixed or dynamic, and the formal bounds must be covered by the actual array second dimension. Column slices are not supported because they are not contiguous in storage.

•For two-dimensional ACCESS ARRAY parameters, whole two-dimensional actual arrays must have matching dimensions and bounds. Larger two-dimensional actual arrays are not accepted.

•Supported element types are elementary types, STRING, and STRUCT_BLOCK. STRUCT_BLOCK elements may contain normal supported members, including strings and arrays.

•Arrays of FUNCTION_BLOCK or THREAD_BLOCK elements are not supported as ACCESS ARRAY parameters.

 

FUNCTION SetGrid : INT;
VAR_INPUT
 grid : ACCESS ARRAY[0..1,0..1] OF INT;
END_VAR;
 
grid[1,1] := 77;
SetGrid := grid[1,1];
END_FUNCTION;

 

The compiler checks ACCESS ARRAY calls at compile time. Common errors include using a non-array actual parameter, passing an indexed array element, selecting something other than a whole ARRAY variable, STRUCT_BLOCK array member, or valid row slice, using an incompatible element type, using one-dimensional actual bounds or row-slice second-dimension bounds that do not cover the formal bounds, using non-identical two-dimensional bounds for whole two-dimensional actual arrays, or using unsupported FUNCTION_BLOCK or THREAD_BLOCK element arrays. No firmware or VM change is required for ACCESS ARRAY parameters; existing runtime bounds checking is preserved.

 

Using ACCESS parameters to a function has many advantages:

 

•In addition to the single return value from a function, an arbitrary number of additional return values can be realized.

•It can often be used easier and with a memory saving if used instead of a FUNCTION_BLOCK.

•ACCESS parameter passing with a STRUCT_BLOCK allows a function to read, modify, or copy caller-owned composite values. This is the recommended method when a function must produce a STRUCT_BLOCK result.

 

.. and only a few rules apply:

 

•All ACCESS parameters must be assigned by the caller.

•The variable types of the formal parameter and the actual parameter must be identical, except for the documented one-dimensional ACCESS ARRAY case where the actual array may be larger if its bounds cover the formal bounds.

 

 

Also see the section on functions in the VPL Introduction Manual.