The LINK, LINK-CLIENT, and LINK_CLIENT_VAR Logic Verbs are used to call subroutines written in another language from PROIV Logic. In the Windows environment, these subroutines are in the Windows DLLs. This is different from other kernel platforms, where subroutines are typically written as C functions, and then linked directly into the kernel or 3GL language for the UNIX. 

This difference has two impacts:

  1. The subroutines must be coded in a DLL.  Typically, this involves adding wrapper code to the subroutine source file.  The example source code provided with the Windows kernel distribution gives a suitable wrapper for subroutines written in C.

  2. The first parameter of a LINK call is used to define the DLL entry point, and therefore, has a more specific meaning than on other platforms.  On other platforms, a single entry point extsub is always called.  In Windows, the first parameter defines both the DLL and the entry point to call.

Other points to note include:

The logic call syntax for LINK is:

LINK($name, $param1, $param2, ..)

 

The logic call syntax for LINK-CLIENT and LINK-CLIENT-VAR is the same:

#stat = LINK-CLIENT($name, $param1, $param2, ..)

 

#stat = LINK_CLIENT_VAR($name,[direction]$param1,[direction] $param2, ..)

where: [direction] A optional prefix indicating whether the parameter is an input to the DLL, an output from the DLL or both. The prefix is one of the following:

%IN% A parameter is an input to the DLL.  Its value is passed to the DLL, but any changes to the parameter by the DLL are not be passed back.

%OUT% A parameter is an output from the DLL.  Its initial value is ignored (blanks are passed to the DLL).  Its value is passed back on return from the DLL.

%BOTH% A parameter is both an input to the DLL, and an output from the DLL.  Its value is passed to the DLL and any changes to the parameter by the DLL are passed back.

Long ALPHA strings are supported on UNIX (i.e. each parameter may be up to 2000 bytes long. The maximum number of parameters is only limited by the PROIV Logic compiler workspace (up to a theoretical limit of 255).

The first parameter is the DLL entry point name.  For LINK-CLIENT and LINK_CLIENT_VAR, the Client processes this parameter.  For LINK, the kernel processes the parameter. Both accept the same syntax, except as noted below:

Parameter List Format Passed to the DLL

Once the entry point to call is located, a parameter list is built.  This is a standard C argc, argv list, with the first argv parameter (argv[0]) being the first parameter passed to the LINK/LINK-CLIENT (for example, the DLL entry point parameter).  Each parameter may be a numeric or string parameter.

Numerics are converted to strings before being passed to the DLL.  This conversion uses a free format (the same code as is used for displaying numbers on the screen).  As this can generate exponent format in some cases (for example, 1.2e23), numerics are normally avoided.  If you want to pass a number, use CONV to convert the numeric to a string in the format preferred and pass the string so you know exactly what format is being passed.

The actual format that a parameter is passed, as is different depending on which verb is used.

For LINK and LINK-CLIENT, each parameter passed is padded to its maximum size with spaces, followed by a null byte.  The maximum length of each parameter is stored in the byte immediately before the first byte of the parameter.  For example: argv[1][-1] might contain the length of $param1 in the above example logic call.  This may be used rather than searching for the null terminator to find out the parameter buffer size. (A current restriction is that the C function strlen is used to calculate this length, so if an ALPHA parameter contains a null character, it only indicates the length up to the first null.)

For LINK_CLIENT_VAR, each parameter is passed without padding (and without a null terminator). There is a 4-byte header at the start of each parameter. The parameter address passed to the DLL is the start of this header (in contrast to LINK/LINK-CLIENT, where the parameter address points after the header):

Byte Position

Use

[0]

Maximum size (high order byte). For output/both parameters, this is the maximum size that can be returned. For input, it will be set to the same value as current size.

[1]

Maximum size (low order byte)

[2]

Current size (high order byte). For output parameters, this will be 0.

[3]

Current size (low order byte).

NOTE: The above size parameters are in big-endian byte order (for example, the opposite order that the two bytes of a short are stored on an Intel PC), so do NOT cast them to (short *) to pick up the size.  Instead, use syntax similar to the following:

Current_size = (parameter[n][0] << 8) | (parameter[n][1] & 0xff);

Maximum_size = (parameter[n][2] << 8) | (parameter[n][3] & 0xff);

For Output and Both parameters, any changed value must be copied back into the parameter area, and the current size (bytes 2 and 3 of the parameter) must be updated to the size of the new value. Note that the new size must not exceed the maximum size value.

extsub.c Skeleton Source

The supplied skeleton source (extsub\extsub.c under the installation directory) uses a table search and switch statement to decide which function to pass a request to. As supplied, this limits you to 10 entry points called SUB0 to SUB9 and a maximum of 10 parameters per entry point.

On Return from the Entry Point

When control returns from the entry point, the parameter list is passed back to the kernel, which then updates the parameters to the logic LINK/LINK-CLIENT/LINK_CLIENT_VAR verb with these values.  Numerics are converted as described above.  For LINK/LINK-CLIENT, the first null located in the parameter string is used to decide the return parameter size. For LINK_CLIENT_VAR, the current size field indicates the return size.

Logic Verb Return Status

The DLL return status is passed back as the result value of the LINK/LINK-CLIENT/LINK_CLIENT_VAR.

The exception to this is for LINK only, if the DLL returns a value of -1, PROIV aborts the function with a system error 182, therefore, do not return -1.

Other Information Available for Use By LINK/LINK-CLIENT/LINK_CLIENT_VAR

LINK-CLIENT/LINK_CLIENT_VAR with Windows Client only: @CLIENTINFO system variable can be used to find handle of Client main window.

Windows Multi-Threading Issues

For LINK with the Windows kernel, the DLL needs to support multiple threads from one process (one thread per connected user). Other scenarios of LINK, and all uses of LINK-CLIENT and LINK_CLIENT_VAR need to support one thread per process with multiple processes.

Comment on this topic

Topic ID: 520016