Using attributes to define Synergy methods

The recommended method for populating the Synergy Method Catalog is to attribute your Synergy code, use the dbl2xml utility to produce an XML file, and then import definitions from the XML file into the SMC. The dbl2xml utility (installed with Synergy/DE Professional Series) parses information about the routines you want to use with xfServerPlus from your Synergy source code. The utility outputs an XML file, which is then imported into the SMC using the MDU’s import facility. When using this method, you are not required to use the MDU to perform data entry.

This topic includes the following: 

Attribute overview

General procedure for attributes

xfMethod attribute

xfParameter attribute

Attribute examples

Documentation comments

Attribute overview

The dbl2xml utility obtains much of the basic information about your routines, such as the routine name and return value data type, from the code itself; however, some types of information, including the interface name, must be provided by adding attribute statements to your code. There are two attributes, xfMethod and xfParameter, each of which has a number of properties. xfMethod is required, but xfParameter may be optional, depending on the type of parameter you are defining.

The example below shows a simple xfMethod attribute statement for the function ReturnError. (See Attribute examples for additional examples.)

{xfMethod(interface="ConsultApp", elb="EXE:Consult")}
function ReturnError       ,string
    req in userToken       ,a22
    endparams

The advantage to attributing your code and using dbl2xml over using the MDU to perform data entry is that your code and SMC are less likely to get out of sync. You may, of course, need to alter the attributes and properties if you change your code, but because the attributes are right there in the source file, you are unlikely to forget to do so. Additionally, you can add the command to run the dbl2xml utility to a build script so that it runs every time you compile. You can also add the MDU command line option to update the SMC to your build script, thereby automating the SMC update process. Although there is some up-front work to implement attributes, once you have done so, using attributes should prove more efficient and accurate than using the MDU to input and maintain data about your routines.

The dbl2xml utility also processes documentation comments in your Synergy code. These comments are imported along with your method definitions into the SMC and can be used to create API documentation for your Java or .NET component. See Documentation comments.

General procedure for attributes

1. Modify your code to include attributes, parameter modifiers, and documentation comments. See the Routine Metadata table for assistance in determining what additions or changes you need to make to your code. For example, if your code does not currently use direction modifiers in parameter definitions, you will need to add them. The only required properties are interface and elb in the xfMethod attribute, but you may need to add others depending on your code and the desired results on the client side.
Note

If you are attributing an existing xfServerPlus–xfNetLink application, pay special attention to how methods are named so that you don’t break existing client code. See the Routine Metadata table for the rules on defaulting.

2. Compile your code and fix any resulting problems.
3. Run the dbl2xml utility on your source files. It will create an XML file that contains interface definitions, and which is named (by default) with the first interface encountered during processing. If desired, you can specify a name for the XML file with the -out option. for example:
dbl2xml VendorMaint.dbl -out c:\work\Vendor.xml

See dbl2xml utility for the complete dbl2xml syntax.

Note

The XML generated by dbl2xml is very similar to that generated by genxml, but it is not exactly the same. The file generated by dbl2xml can be used only to update the SMC; it cannot be read by genjava or gencs.

4. Run the MDU from the command line with the -u option or open the MDU application and select Utilities > Import Methods to import the data from the XML into the SMC. For example,
dbr dbldir:mdu d:\synergy\smcFiles -u c:\work\Vendor.xml 
5. In the future, when you make changes to your Synergy code, make the corresponding changes to the attributes (if necessary), and then repeat step 2 through step 4 above.
Tip

You may want to check your results in the MDU after importing the XML file to ensure methods and parameters are defined as you intended. Pay special attention if you rely on default sizes for return values and parameters, as the data type conversion for the client sometimes depends on the size defined in the SMC. See the type mapping tables in Appendix B: Data Type Mapping for xfNetLink Java and Appendix C: Data Type Mapping for xfNetLink .NET.

Routine metadata and where it comes from

The table below summarizes the information that xfServerPlus needs to know about your routines and indicates whether that information is obtained from source code, attributes, or default values. The applicable attributes and properties are included in the table; click on the links to see the exact syntax and details on usage.  

Routine Metadata

Item

Source/Comments

Attribute

Property

Routine name

The function or subroutine name is obtained from the source code.

N/A

N/A

Method name

Defaults to the Synergy routine name, but can be overridden with the name property. See name .

xfMethod

name=”xxx

Method ID

Defaults to the Synergy routine name or to the method name if the name property is used. Can be overridden with the id property. See id  .

xfMethod

id=”xxx

Interface name

Specified with the interface property. This property is required. See interface.

xfMethod

interface=”xxx

ELB name

Specified with the elb property. This property is required. See elb .

xfMethod

elb=”xxx

Return value data type

Obtained from the function definition or, if not specified there, defaults to the data type of the variable or literal of the first FRETURN statement. (In other words, the same way the compiler determines the return value data type.)

To coerce the data type to a non-default type on the client, use the cType property; see cType .

Return values that are coerced to DateTime data type require the format property; see format . DateTime return values can be created as nullable types on the client using the nullable property; see nullable .

xfMethod

cType=xfType.xxx

format=xfFormat.xxx

nullable=true

Return value size

Obtained from the function definition or, if not specified there, a default value is used for most data types; else, you must specify it with the length property (and precision property, if necessary). See length, precision .

xfMethod

length=xxx

precision=xxx

Parameter name

Defaults to the declared Synergy parameter name, but can be overridden with the name property. See name .

xfParameter

name=”xxx

Parameter direction

Obtained from parameter modifiers (IN, OUT, INOUT) in the source code. If not supplied, defaults to IN. See Defining a parameter.

N/A

N/A

Parameter required/optional

Obtained from parameter modifiers (REQ, OPT) in the source code. If not supplied, defaults to required. See Defining a parameter. (For Java and .NET clients, any parameter marked optional in the SMC is changed to required when the component is built.)

N/A

N/A

Parameter size

Obtained from the parameter definition or, if not specified there, a default value is used for some data types; else, you must specify it with the length property (and precision property, if necessary). See length, precision .

xfParameter

length=xxx

precision=xxx

Parameter data type

Obtained from the parameter definition for most data types. In some cases, must be specified with the type property. See type .

To coerce the parameter to a non-default type on the client, use the cType property; see cType .

Parameters that are coerced to DateTime require the format property; see format . A DateTime parameter can be created as a nullable type on the client using the nullable property; see nullable .

For structures passed as parameters or arrays, the data type is obtained from the parameter definition (which must be defined as a structfield). See example B (parameter) and example J (array).

For structures passed as ArrayLists or structure collections, use the collectionType and structure properties. See collectionType .

To specify that an array or ArrayList of structures be created as a DataTable on the client, use the dataTable property. See dataTable .

Group arguments defined in the data division are processed as a single field of the type and size specified. If no type is specified, it defaults to alpha.

Group arguments included from the repository are processed as a single field of type alpha, with the size taken from the repository.

xfParameter

type=SynType.xxx

cType=xfType.xxx

format=xfFormat.xxx

nullable=true

collectionType=
  xfCollectType.xxx

structure=”xxx

dataTable=true  

xfMethod attribute

{xfMethod(property=value, property=value, ...)}

The xfMethod attribute describes a subroutine or function. (Synergy object-oriented methods are not supported.) It indicates that the subroutine or function following the attribute is intended for use with xfServerPlus and should be included in the generated XML file when dbl2xml is run. xfMethod must be used before each subroutine or function that you want included in the SMC. A routine may have more than one xfMethod attribute to indicate that it needs to be included in more than one interface. The properties that can be used with xfMethod are listed below. The interface and elb properties are required. Depending on the routine, you may need to specify other properties as well.

Note

When attributing code for use with a Synergy/DE Interop project in Visual Studio, the only required property of the xfMethod attribute is interface. The elb, id, and encrypt properties are not used. Other properties may be necessary depending on your code. For more information about interop projects, see Converting xfServerPlus routines for native .NET access.

interface

interface="name"

(required) The interface in which you want this method to be included. The quotation marks are required. Valid values for interface name are alphanumeric characters and the underscore character ( _ ); it must begin with an alpha character. The interface name is case sensitive.

Note

Although the interface name is case sensitive, we do not recommend creating interface names that differ only in case. If you attempt to generate a component that contains two or more interfaces that differ only in case, the genjava or gencs utility will append a number (starting with 1 and incrementing) to the end of each of the additional interfaces to create unique class names (e.g., MYINTFACE, MyIntFace1, myintface2, etc.). You will also see numbers appended to class names when there is a structure name that is the same as an interface name. Because structure classes are processed first, it is the procedural class name that will be altered.

For xfNetLink .NET, the interface name and method name must be different. Matching interface and method names cause the error “member names cannot be the same as their enclosing type” when the classes are compiled.

You may have only one instance of the interface property within an xfMethod attribute. If a routine needs to be included in more than one interface, you must create a separate instance of the xfMethod attribute for that routine. See example B.

Methods are grouped into interfaces for inclusion in a Synergy component. The interface name will be used to select interfaces to include in the component, and users will see it as the class name when they use your JAR file or assembly. Although the interface is not used by xfNetLink Synergy, it is required for the XML that dbl2xml generates. Since interface name has no meaning for xfNetLink Synergy, you can use the same interface name for all methods if desired.

Tip

To reduce the amount of typing you have to do, you may want to use .DEFINEs to specify values for properties that occur numerous times in your code, such as interface name and elb name. For example,

.define myinterface interface="Login"
.define myelb elb="EXE:utils"

{xfMethod(myinterface, myelb)}

elb

elb="path"

(required) The ELB or shared image in which the Synergy subroutine or function is implemented. You may use a complete path or a logical. The file extension (.elb or .exe) is not required. Maximum length is 255 characters.

Note

If you use a logical in the elb property, you must define the logical in the xfpl.ini file (SERVER_INIT.COM on OpenVMS) so that xfServerPlus knows how to resolve it. See Defining logicals.

name

name="methodName"

Overrides the default method name, which is the same as the Synergy routine name. Valid values for method name are alphanumeric characters and the underscore character ( _ ). The method name must begin with an alpha character. The maximum length is 50 characters. The name must be unique for the interface. (This comparison is case insensitive.)

The name value is also used as the method ID, unless the id property is specified (see below). If the method name is longer than the maximum size of the method ID (31 characters), it is truncated to create the ID. Note that truncation could result in non-unique IDs, which are not permitted. For more information about method name and routine name, see Understanding routine name, method name, and method ID.

Note

Although the $ character is valid in routine names in Synergy DBL, it is not valid for method names (or method IDs) in the SMC. If you use $ in your routine names, be sure to use the name property to specify a valid method name.

id  

id="methodID"

Overrides the default method ID, which is either the Synergy routine name or, if the name property is used, the method name. Valid values for method ID are alphanumeric characters and the underscore character ( _ ). The method ID must begin with an alpha character. The maximum length is 31 characters. The method ID must be unique within an SMC.

In most circumstances, you will not need to specify the id property. But there may be cases where defaulting the method ID from the routine name or method name results in a non-unique method ID; in these cases, you need to specify the id property. See example B for a case in which id is required. Because the method ID must be compared with any method IDs that are already in the SMC, the check for uniqueness cannot take place until the XML file is imported into the SMC. For more information on the method ID and how it is used by xfServerPlus, see Understanding routine name, method name, and method ID.

length, precision

length=##
precision=##

The size of the function return value. For most data types, the size is obtained from the function definition, and if the size cannot be so obtained, a default value is used. (See table below.) You can override this default by specifying the size in the function definition or with the length and (for implied-decimal) the precision properties. For alpha data types, you must use the length property if the size is not specified in the function definition, as there is no default value. Supported data types that are not included in the table below either have a size of 0 in the XML or have a default size that cannot be overridden.

Data type

Default if not specified in code

Alpha (a)

N/A - Must be specified in code or with the length property.

Decimal (d)

18

Implied-decimal (d.)

Decimal (decimal)

28.10

Integer (i, int, or integer)

4

^VAL

4

cType

cType=xfType.ret_type

Specifies a non-default data type for the return value to be coerced to on the client side. This feature is supported for Java and .NET clients only. Decimal, implied-decimal, and integer data types can be coerced. See the table below for the valid ret_type values for each data type. See example D. (This example shows type coercion for a parameter, but the principal is the same for the return value.) See Appendix B: Data Type Mapping for xfNetLink Java and Appendix C: Data Type Mapping for xfNetLink .NET for more information on data type mapping and coercion.      

Tip

Data types byte, sbyte, short, int, long, and Boolean are built-in data types in Synergy DBL that map to integers. Consequently, you can use these data types directly in the function definition, rather than specifying an integer and then using the cType property to specify a non-default coerced type. See Data types for more information on these types.

cType Property Values

Return value data type

Valid coerced types

xfNetLink Java

xfNetLink .NET

Decimal (d)

byte

short

int (coerced to Integer)

long

Boolean

DateTime (coerced to Calendar)

decimal (coerced to BigDecimal)

byte

short

int

long

sbyte

ushort

uint

ulong

Boolean

DateTime

decimal

Implied-decimal (d.)

decimal (coerced to BigDecimal)

double

float

decimal

double

float

Integer (i)

byte

short

int (coerced to Integer)

long

Boolean

byte

short

int

long

sbyte

ushort

uint

ulong

Boolean

format

format=xfFormat.format

The format for a DateTime return type. The format property is required when the cType property is DateTime. The valid values for format are shown below. These values are case insensitive.

nullable

nullable=true

Indicates that a nullable DateTime or decimal return type is desired on the client side. This option is supported for .NET clients only. The nullable property is valid only when the cType property is DateTime or decimal. “False” is a valid value and is the same as not setting the property.

encrypt

encrypt=true

Indicates that encryption is required for this method. Starting with version 11.1, xfServerPlus supports only master encryption; consequently, including this attribute is optional, but it acts as a fail-safe. If the method is marked for encryption in the SMC but encryption is not enabled on the server, the error “Method requires encryption” is generated. See Ensuring that specific methods are encrypted for more information. “False” is a valid value and is the same as not setting the property.

xfParameter attribute

{xfParameter(property=value, property=value, ...)}

The xfParameter attribute describes the parameters in a routine. xfParameter is not required; use it only when the necessary metadata for the parameter cannot be determined from the code. Only one instance of the attribute is permitted per parameter. The properties that can be used with xfParameter are listed below.

name

name="paramName"

Overrides the default parameter name, which is the name of the declared Synergy parameter. Valid values for parameter name are alphanumeric characters and the underscore character ( _ ). The name must begin with an alpha character. The maximum length is 50 characters. The name must be unique for the method. (This comparison is case sensitive.)

Note

Although the $ character is valid in parameter names in Synergy DBL, it is not valid in parameter names in the SMC. If you use $ in parameter names, be sure to use the name property to specify a valid name for the SMC.

type

type=SynType.data_type

Specifies the data type. These are the valid values for data_type:

When using this property, the Synergy parameter must be a memory handle (an i4; do not use int). For more information on using a memory handle to pass large, variable length, or binary data see the following:

length, precision

length=##
precision=##

The size of the parameter. If the size is included in the parameter definition, it is used. If the size is not included in the definition, a default value is used for some data types. (See table below.) You can override this default by specifying the size in the definition or with the length property (and, for implied-decimal data, the precision property). For alpha data types, you must use the length property if the size is not specified in the parameter definition, as there is no default value. This includes System.Collections.ArrayList parameters in which the elements are alphas.

Supported data types that are not included in the table below either have a size of 0 in the XML or have a default size that cannot be overridden.    

Data type

Default size

Alpha (a)

N/A - Must be specified in parameter definition or with the length property.

Decimal (d)

18

Implied-decimal (d.)

Decimal (decimal)

28.10

Integer (i, int, or integer)

4

Numeric (n)

18

Implied numeric (n.)

28.10

Note

Not all parameter data types are supported on all clients. See the Supported Parameter Data Types and Collection Types by Client table.

cType

cType=xfType.data_type

Specifies a non-default data type for the parameter to be coerced to on the client side. Decimal, implied-decimal, and integer data types can be coerced. This feature is supported for Java and .NET clients only. See the cType Property Values table for the valid cType values for each data type. See example D. See Appendix B: Data Type Mapping for xfNetLink Java and Appendix C: Data Type Mapping for xfNetLink .NET for more information on data type mapping and coercion.

Tip

Data types byte, sbyte, short, int, long, and Boolean are built-in data types in Synergy DBL that map to integers. Consequently, you can use these data types directly in the parameter definition, rather than specifying an integer and then using the cType property to specify a non-default coerced type. See Data types for more information on these types.

format

format=xfFormat.format

Indicates the format for a DateTime parameter. The format property is required when the cType property is DateTime. The valid values for format are shown below. These values are case insensitive.

nullable

nullable=true

Indicates that a nullable DateTime or decimal parameter is desired on the client side. This option is supported for .NET clients only. The nullable property is valid only when the cType property is DateTime or decimal. “False” is a valid value and is the same as not setting the property. See example E.

collectionType

collectionType=xfCollectType.data_type

Indicates the data type of the elements when the parameter is a System.Collections.ArrayList or a structure collection. This feature is supported on Java and .NET clients only. For structure collections, the collectionType property is always “structure” and is used in conjunction with the structure property. (See below.) For an ArrayList of structures, you must also use the structure property to specify the structure name.

Valid values for data_type are as follows:

See example H for a structure collection, example C for an ArrayList of structures, and example I for an ArrayList of alphas.

structure

structure="structureName"

Specifies the structure name when the parameter is a structure collection or ArrayList of structures. Used only in conjunction with the collectionType property. See example H.

Important

If your code renames structures using a .INCLUDE directive like this

.include "STRUCT_1" REPOSITORY, structure="STRUCT_2" ,end

use the new name (STRUCT_2 in the example) in the property, not the original name. The dbl2xml utility will map the name in the property to the original name and write the latter to the XML. See example C.

dataTable

dataTable=true

Indicates that the System.Collections.ArrayList or structure collection parameter should be created as a DataTable on the client. This feature is supported on .NET clients only. “False” is a valid value and is the same as not setting the property. Used only in conjunction with the collectionType property. See Using DataTables for more information on DataTables.

Attribute examples

A. This is a basic example that shows the xfMethod attribute for a function. The xfMethod attribute includes the interface name and ELB path (which uses a logical); no other properties are required. The method and method ID will default to the function name. No xfParameter attribute is required because all the necessary parameter information (name, direction, data type, size) is included in the definition.
{xfMethod(interface="ConsultApp", elb="EXE:Consult")}
function ReturnError       ,string
    req in userToken       ,a22
    endparams
B. This example shows the xfMethod and xfParameter attributes for a function that is included in two interfaces. The method name (Login) will be the same in both interfaces. The method ID for the first xfMethod attribute will default from the method name, but we must supply an ID for the second attribute, as the ID must be unique.

For the three parameters, the xfParameter attribute includes the name property, since the declared parameter name includes the character $, which is invalid in the SMC. The third parameter is a structure; the associated repository structure is .INCLUDEd. When using dbl2xml, structures passed as ordinary parameters and as arrays must be defined as structfields in your Synergy code. (See structure for information on structfields.)

Note

When an attribute follows a .INCLUDE directive, as in the example below, the END qualifier is required. (Normally, when you .INCLUDE a global structure, the END qualifier is not required, though it is recommended, and the compiler will issue a warning if it’s not specified.)

.include "USER" REPOSITORY, structure, end
{xfMethod(interface="Cust", name="Login", elb="EXE:Consult")} 
{xfMethod(interface="Vendor", name="Login", id="loginV", elb="EXE:Consult")}
function alogin ,^val
{xfParameter(name="userID")}
    req in a$id        ,a10    ;User id
{xfParameter(name="userPword")}
    req in a$password  ,a8     ;User password
{xfParameter(name="userData")}
    req out a$user     ,USER   ;User info record
    endparams
Note

If you do this in your code

.subroutine mysub
   req in arg1   ,a10
   .include "fred" repository, req out group="arg2"
   req out arg3  ,d8
endparams

the parameter included from the repository will not be processed as a structure. Rather, it will be processed as a single alpha field of the size specified in the repository. If you want to preserve the fields in a group argument when you generate classes for the client side, you should .INCLUDE the structure globally and then define the parameter as a structfield, as shown above in example B.

C. This example shows a function with two parameters. The function returns a Boolean data type (see the tip under cType ). For the first parameter, we don’t need an attribute because all the necessary information is in the code. The second parameter is an ArrayList in the Synergy code; on the client, we want to create an ArrayList of structures as a DataTable. To accomplish this, we specify the collectionType property (which specifies the type of elements in the ArrayList), the structure name, and the dataTable property. Note that we use the redefined structure name (country), not the original name (cntry) in the property.
.include "CNTRY" REPOSITORY, structure="country", end
{xfMethod(interface="ConsultApp", name="getCountryTable", elb="EXE:Consult")} 
function get_country_table ,boolean
    req in  userToken      ,a22
    {xfParameter(collectionType=xfCollectType.structure, structure="country", dataTable=true)}
    req out countryTable   ,@System.Collections.ArrayList
    endparams 
D. This parameter example shows a parameter defined as a d8, which is coerced to a DateTime data type, using the cType and format properties.
{xfParameter(cType=xfType.DateTime, format=xfFormat.YYYYMMDD)}
req out updateDate ,d8
E. This example is the same as above, but the DateTime data type will be created as a nullable DateTime on the client:
{xfParameter(cType=xfType.DateTime, format=xfFormat.YYYYMMDD, nullable=true)}
req out updateDate ,d8
F. This parameter example shows a parameter that will be used to pass large or variable size data. The parameter is a memory handle (i4) in the Synergy code, and we set the type property to “handle”. (See Passing a single parameter as a memory handle for more information on using this feature.)
{xfParameter(name="largeParam", type=SynType.handle)}
req inout memHandle ,i4         ;Mem handle for large param
G. This parameter example shows a parameter that will be used to pass binary data. The parameter is a memory handle (i4) in the Synergy code, and we set the type property to “binaryhandle”. This will result in an ArrayList on a Java client and a byte array on a .NET client. (See Passing binary data for more information on using this feature.)
{xfParameter(name="fileData", type=SynType.binaryhandle)}
req out memHandle ,i4          ;Mem handle for binary data
H. This parameter example shows a parameter that will be used to pass a structure collection, which will be created as a DataTable on the .NET client. In the Synergy code, the parameter is defined as a memory handle (see Returning a collection of structures). The xfParameter attribute includes the structure property (for the structure name), the collectionType property to indicate the data type (which is structure in this case), and the dataTable property.
.include "USER" REPOSITORY, structure, end
. 
.    ;routine definition and xfMethod attribute go here
.
{xfParameter(name="CustList", structure="User", collectionType=xfCollectType.structure, dataTable=true)}
req out memHandle ,i4    ;Mem handle for structure collection
I. This parameter example shows an ArrayList of alphas. The collectionType property specifies that the data type of the elements in the ArrayList is alpha. Because there is no default size for alphas, we include the length property.
{xfParameter(collectionType=xfCollectType.alpha, length=30)}
req inout cityList ,@System.Collections.ArrayList 
J. This parameter example shows an array of structures and an alpha array. The arrays must be real arrays, not pseudo arrays or dynamic arrays. Include the size of an array element in the parameter definition or with the length property. The structure must be defined as a structfield. Because all the information is included in the parameter definition, the xfParameter attribute is not required.
.include "USER" REPOSITORY, structure, end
. 
.    ;routine definition and xfMethod attribute go here
.
req inout myStructArray ,[*]user ;Array of structures
req inout myAlphaArray  ,[*]a10  ;Alpha array 

Documentation comments

When attributing your code, you can include documentation comments, which will be processed by dbl2xml, included in the XML file, and then imported into the SMC. When you generate classes for xfNetLink Java or xfNetLink .NET, the comments are included in the generated code. You can then use the comments to generate Javadoc or API documentation. Documentation comments are not supported for xfNetLink Synergy. (Their presence in the SMC does not represent an error condition; they are just ignored.)

For details on using comments to generate documentation, see the following:

You can add comments for methods, return values, and parameters. Each type of comment is distinguished by a particular tag, as explained in Comment tags below.

Follow these rules when adding doc comments:

;;; <summary>This is a comment</summary>

Comments apply to the routine that they precede. For readability, we recommend that you put them together in a block either immediately before or immediately after the associated xfMethod attribute. Do not put a documentation comment on the same line as the xfMethod attribute; it will be ignored.

summary

<summary> </summary>

Use the <summary> tag for comments that describe the function or subroutine. Only one tag is permitted per routine.

returns

<returns> </returns>

Use the <returns> tag for return value comments. Valid only for functions. Only one tag is permitted per function.

param

<param name= "paramName"> </param>

Use the <param> tag for parameter comments. Use a separate tag for each parameter and use the name property to specify which parameter the comment pertains to. The name in the comment tag should match the value of the name property in the xfParameter attribute, if it is used; else, it should match the name of the parameter in the source code. This comparison is case sensitive.

The example below includes comments for the method (summary), return value, and each of the three parameters. Comments longer than 50 characters are broken into two lines. Note that for the third parameter, the name in the <param> tag matches the name specified with the name property of the xfParameter attribute.

{xfMethod(interface="ConsultApp", elb="EXE:Consult")} 
;;;<summary>
;;;Logs user into application and verifies ID and password
;;;</summary>
;;;<returns>Indicates success or failure</returns>
;;;<param name="a_id">User ID</param>
;;;<param name="a_password">User password</param>
;;;<param name="User">
;;;User record containing user first name, last name, and 
;;; maximum billing rate.
;;;</param>
.function alogin   ,^val
req in a_id        ,a10
req in a_password  ,a8
{xfParameter(name="User")}
req out a_user     ,user     ;USER structure
    endparams