![]() |
|
In order to successfully construct external call tables, you should be familiar with VMS descriptors. |
External calls can receive output strings from external routines in two ways. The first method requires the external routine to allocate space for the output string; this is particularly useful when the length of the output string is unknown or is likely to vary significantly. In the second method, the external call preallocates string space before passing the descriptor to the external routine. This method is particularly convenient when calling the VMS Run-time Library routines directly.
To allocate space for output strings within the called routine:
Use the empty dynamic string descriptor provided by GT.M. An output of TYPE=STRING, MECHANISM=DESCRIPTOR that does not have QUALIFIER=PREALLOCATE causes the external call to pass an "empty" dynamic descriptor; that is, a descriptor marked as dynamic with no associated buffer space and no preset size. This descriptor type allows the VMS library routines that manipulate descriptors to create and manage space for the descriptor as needed.
In the external routine, allocate memory for the output string using one of three VMS library routines:
LIB$SGET1_DD
LIB$SCOPY_DXDX
LIB$SCOPY_R_DX
These routines manipulate dynamic descriptors, creating buffer space for them as necessary. The external call frees this space when GT.M resumes control. For more information on these library routines, refer to OpenVMS RTL Library (LIB$) manual.
A dynamic descriptor can be overwritten to point at static memory by changing the DSC$W_LENGTH, DSC$A_POINTER, DSC$B_CLASS, AND DSC$B_TYPE. This should be done only with dynamic descriptors, if at all.
To pass output strings using preallocated string space:
In the external call table, specify the PREALLOCATE qualifier on the output line.
In the external call table, specify the maximum possible length of the output string with the VALUE keyword on the output line. This must be less than 32767.
In the called routine, write the output string data into the buffer described by the output descriptor, being careful not to write more to the buffer than provided (as indicated by the initial value of the DSC$W_LENGTH field of the output descriptor).
In the called routine, write the length of the resultant output string into the DSC$W_LENGTH field of the output descriptor. (This may be handled automatically, depending on which VMS routine you use to allocate memory.) This value must NOT exceed that specified with the VALUE keyword on the output line.
Do NOT alter the DSC$A_POINTER field of the output descriptor.
Example:
.title zctablexample .library "gtm$dist:gtmzcall.mlb" zcinit routinecallname=lexp, linkname=lexp, outputs=1 returnclass=status outputposition=1, qualifier=preallocate, - mechanism=descriptor, type=string, value=255 zcallfin .end
This shows an output that is PREALLOCATEd and has a buffer size of 255 bytes. The hyphen (-) in the last position of the line, for example, at the end of the output line, acts as a line continuation in MACRO.