Page History
...
This Built-In Function might be accessed in the LANSA RDML language like this:
...
define field(#number1)
...
type(*dec)
...
length(7)
...
define field(#number2)
...
type(*dec)
...
length(7)
...
define field(#mean)
...
type(*dec)
...
length(7)
...
request fields(#number1 #number2)
use ud_average with_arg(#number1 #number2) to_get(#mean)
...
pop_up fields(#mean)
...
Following is a C user-defined Built-In Function definition called UD_AVERAGE that receives 2 decimal values as arguments and returns their average value.
...
While this Built-In Function is trivial and the example of its use is trivial, it is a simple starting point:
BIF Definition (as per DC@F47 file on IBM i/ LX_F47 file on Windows)
BIF Name: | UD_AVERAGE |
Unique Identifier: | 413 |
Description: | Retrieve a system value |
Call or Execute: | C |
Program Name: | U_BIF413 |
Terminates between calls: | N (Y or N) |
Number of arguments: | 2 |
Number of return values: | 1 |
BIF Arguments (as per DC@F47 file on IBM i/ LX_F47 file on Windows)
Parameter 1
BIF Name: | UD_AVERAGE |
Parameter Type | ARG |
Parameter Sequence: | 1 |
Parameter Number: | 1 |
Parameter Identifier: | A |
Description: | First Value |
Required / Optional: | R (R or O) |
Parameter Type: | N (A, N or L) |
Minimum Length: | 7 |
Maximum Length: | 7 |
Minimum Decimal: | |
Maximum Decimal: | |
Pass Length: | 10 |
Pass Decimal: | |
Default: |
Parameter 2
BIF Name: | UD_AVERAGE |
Parameter Type | ARG |
Parameter Sequence: | 2 |
Parameter Number: | 2 |
Parameter Identifier: | B |
Description: | Second Value |
Required / Optional: | R (R or O) |
Parameter Type: | N (A, N or L) |
Minimum Length: | 7 |
Maximum Length: | 7 |
Minimum Decimal: | |
Maximum Decimal: | |
Pass Length: | 10 |
Pass Decimal: | |
Default: |
BIF Return Values (as per DC@F47 file on IBM i/ LX_F47 file on Windows)
BIF Name: | UD_AVERAGE |
Parameter Type | RET |
Parameter Sequence: | 1 |
Parameter Number: | 3 |
Parameter Identifier: | C |
Description: | Mean Value |
Required / Optional: | R (R or O) |
Parameter Type: | A (A, N or L) |
Minimum Length: | 7 |
Maximum Length: | 7 |
Minimum Decimal: | |
Maximum Decimal: | |
Pass Length: | 256 |
Pass Decimal: |
Now, enter the data into the Built-In Function definition files:
/*
...
===============================================================
...
*/
/*
...
==========
...
USER DEFINED BUILT-IN FUNCTION DEFINITION ==========
...
*/
/*
...
===============================================================
...
*/
/* */
...
/* This is a sample of how a user defined built-in function may be */
/* defined. It is provided as an example only. No warranty of any */
/* kind is expressed or implied. The programmer copying this code */
/* is responsible for the implementation and maintenance of this */
/* function, both initially and at all times in the future. */
/* */
...
/* User defined built-in functions are a powerful facility. However,*/
...
/* you should note that YOU are responsible for any impact the */
/* use of a user defined built-in function has on the performance, */
/*
...
security,
...
integrity, portability and maintainability of your */
/*
...
applications. */
/* *
...
/
/*
...
================================================================
...
*/
/* */
/*
...
Source File : U_BIF413.C */
/*
...
Entry Point Name : U_Builtin_413 */
/*
...
Linked DLL Name : U_BIF413.DLL *
...
/
/* Shared Object Name : u_bif413.O */
/*
...
OS/Dependencies :
...
Yes/No */
/* */
/*
...
Amendment History : */
/* */
/*
...
Task Id Date Description */
/*
...
======= ==== =========== */
/* */
/*
...
================================================================
...
*/
...
#define U_BIF_FUNCTION U_Builtin_413
...
#define U_BIF_FUNCTION_
...
NAME "U_Builtin_413"
...
#define U_BIF_DESCRIPTION "
...
This is a description of this built-in"
...
#include <string.h>
...
#include <stdlib.h>
...
#include <stdio.h>
...
#include <limits.h>
...
#include "x_glodef.h"
...
#include "x_glousr.h"
...
#ifdef X_OPERATING_SYSTEM_WIN
...
#include <windows.h>
#endif
...
#include "x_funstr.h"
...
#include "x_funpro.h"
...
#include "x_bif000.h"
/*==================================================================*/
/* */
...
/*
...
Arguments :
...
pX_Ids -
...
Standard X_IDS system definition */
/* pX_Pro -
...
Standard X_PRO process definition */
/* pX_Fun -
...
Standard X_FUN function definition */
/* pX_Bif
...
- Standard X_BIF built-in definition */
/* X_Fld[: -
...
Standard X_FLD field definitions */
/* X_List[: -
...
Standard X_LIST list definitions */
/* sInCount - Number of arguments passed in */
/* sInVec[: -
...
Vectors of arguments */
/* sRetCount -
...
Number of return values */
/* sRetVec[: -
...
Vectors of return values */
/*==================================================================*
...
/
X_VOID_
...
FUNCTION U_BIF_
...
FUNCTION (
...
U_BIF_STANDARD_
...
PARAMETERS )
{
/*
...
-------------------------------------------------------------
...
*/
/*
...
Handle a shutdown request (usually no activity is required) */
...
/*
...
-------------------------------------------------------------
...
*/
...
if (U_BIF_SHUTDOWN_REQUEST)
{
U_BIF_SET_GOOD_RETURN
}
/*
...
-------------------------------------------------------------
...
*/
/*
...
Else perform the requested activity */
/*
...
-------------------------------------------------------------
...
*/
else
{
X_
...
LONG lArg1;
X_
...
LONG lArg2;
X_
...
LONG lAverage;
/*
...
-------------------------------------
...
*/
/*
...
Get argument 1 (C convention is 0) */
/*
...
and argument 2 (C convention is 1) */
/*
...
and compute their average */
/*
...
-------------------------------------
...
*/
...
U_BIF_GET_ARG_AS_
...
LONG (0,lArg1)
U_BIF_GET_ARG_AS_
...
LONG (1,lArg2)
...
lAverage = (lArg1 + lArg2) / 2;
/* -------------------------------------
...
*/
...
/* Return the result in return value 1 */
/*
...
(C convention is 0) */
/*
...
-------------------------------------
...
*/
U_BIF_SET_RET_FROM_
...
LONG (0,
...
lAverage);
/*
...
-------------------------------------
...
*/
/*
...
Set a "good"
...
return (Operating Level) */
/*
...
-------------------------------------
...
*/
U_BIF_SET_GOOD_RETURN
}
/*
...
-------------------------------------------------------------
...
*/
...
/* Return control to caller */
/*
...
-------------------------------------------------------------
...
*/
U_BIF_RETURN;
}
Some significant things to note about this example are:
The very extensive use of C macros. All the U_BIF_xxxx references are to macros contained in header (.H) file X_BIF000.H.
These are expanded at compile time into C code. By using these wherever possible as your "interface" between your Built-In Function and the Visual LANSA definitions and call interface, you can protect your application from future changes.
There are a number of U_BIF macros available. Refer to Shipped U_BIF Macros for a complete list.The definition of local variables by using types such as X_LONG. These definitions are contained in the standard header file X_GLODEF.H and are shipped with Visual LANSA. Variables passed into U_BIF macros should always be declared using these types (as indicated in the macro definition):
Variable Declaration | Pointer Declaration | Actual C Type involved |
|---|---|---|
X_VOID | X_PVOID | Void |
X_BOOL | X_PBOOL | Int |
X_SHORT | X_PSHORT | Short |
X_USHORT | X_PUSHORT | unsigned short |
X_LONG | X_PLONG | Long |
X_ULONG | X_PULONG | unsigned long |
X_LONGLONG | X_PLONGLONG | LONGLONG in Windows: 64 bits signed Integer. Not recommended if used with WATCOMC |
X_DOUBLE | X_PDOUBLE | double |
X_CHAR | X_PCHAR | char (single character only) |
X_VCHAR | X_PVCHAR | char ( > 1 character with a null/end of string terminator) |
X_LIST_COUNT | X_LIST_COUNT * | Long |
The use of the C numbering convention. By convention most C objects are numbered by offset (i.e. "N" things are numbered from 0 to N-1).
This convention is used in all the U_BIF macros. So "Argument Number 3" is actually referenced in U_BIF macros as number 2.
Generally this approach makes coding easier. For example, you might make this function more generic and receive from 2 to 20 numbers as arguments (i.e. no zero divide test is required). To do this you might change the body of the function to be like this:
{
...
X_LONG lArgValue;
X_LONG lArgValue;
X_SHORT sTotalArgs;
...
X_SHORT sCurrentArg;
X_DOUBLE dTotal = 0;
X_SHORT sCurrentArg;
X_DOUBLE dTotal = 0;
U_BIF_GET_ARGUMENT_
...
COUNT (sTotalArgs)
...
for (sCurrentArg = 0; sCurrentArg < sTotalArgs; sCurrentArg++)
...
{
...
{
U_BIF_GET_ARG_AS_
...
LONG (sCurrentArg,
...
lArgValue)
...
dTotal = dTotal + lArgValue;
}
lAverage = dTotal / sTotalArgs;
...
dTotal = dTotal + lArgValue;
}
lAverage = dTotal / sTotalArgs;
U_BIF_SET_RET_FROM_
...
LONG (0,
...
lAverage)
...
U_BIF_SET_GOOD_
...
RETURN
}