Partager via


Parameters in External Libraries

You can pass arguments to parameters when Visual FoxPro calls an ActiveX control, COM object, or Visual FoxPro dynamic-link library (FLL). For example, an ActiveX control might accept arguments when calling one of its methods. Similarly, a Visual FoxPro program might call a function in your FLL library and pass arguments to it.

Visual FoxPro can pass arguments to parameters in an external library by value or by reference. By default, the setting of the SET UDFPARMS command is respected. However, other variables, such as arrays or fields, and expressions are passed by value. For information about how to change the default way of passing arguments, see Passing Data to Parameters.

Because ActiveX controls and COM objects are Windows-standard programs, no special mechanism is required to pass arguments from Visual FoxPro to parameters in an ActiveX control or COM object. You can write library code as if it were receiving arguments from any C or C++ program.

However, functions in an FLL library use the FoxInfo structure to receive data from Visual FoxPro. The FoxInfo structure lists library functions and the number and type of parameters they expect. For example, the following FoxInfo structure belongs to a library with one function, internally called dates, that accepts one Character parameter:

FoxInfo myFoxInfo[] = {
   { "DATES", (FPFI) dates, 1, "C" }
};

Functions you define in external libraries actually receive only one parameter, a pointer to the parameter block. This parameter block, defined in the ParamBlk structure, stores all the information about the parameters that were passed from the Visual FoxPro function call. The following code illustrates the format that your function declaration should follow:

void function_name(ParamBlk *parm)

For example, the function definition for dates is:

void dates(ParamBlk *parm)

The ParamBlk structure consists of an integer that represents the number of parameters, immediately followed by an array of parameter unions. The structure definition is included in Pro_ext.h:

/* A parameter list to a library function.      */
typedef struct {
   short int pCount;      /* number of parameters passed */
   Parameter p[1];         /* pCount parameters */
} ParamBlk;

The Parameter typedef included in the ParamBlk structure is a union of a Value structure and a Locator structure. Call by value is handled by a Value structure; call by reference is handled by a Locator structure. You use these structures to access the parameters passed to your function when the function is called in Visual FoxPro.

The following information is extracted from the file Pro_ext.h and shows the definition of the Parameter type:

/* A parameter to a library function.         */
typedef union {
   Value val;
   Locator loc;
} Parameter;

Value Structure Definition

If a parameter is passed to your function by value, use the Value structure to access it. The following Value structure definition is extracted from the Pro_ext.h file:

// An expression's value.
Typedef struct {
   char         ev_type;
   char         ev_padding;
   short         ev_width;
   unsigned      ev_length;
   long         ev_long;
   double         ev_real;
   CCY         ev_currency;
   MHANDLE      ev_handle;
   ULONG         ev_object;
} Value;

Value Structure Fields

The following table is a guide to the values you can pass and receive in the Value structure for different types of data. Only the structure fields listed for a data type are used for that data type.

Contents of Value structure for different data types

Data type

Structure field

Value

Character

ev_type

'C'

 

ev_length

string length

 

ev_handle

MHANDLE to string

Numeric

ev_type

'N'

 

ev_width

Display width

 

ev_length

Decimal places

 

ev_real

Double precision

Integer

ev_type

'I'

 

ev_width

Display width

 

ev_long

Long integer

Date

ev_type

'D'

 

ev_real

Date1

Date Time

ev_type

'T'

 

ev_real

Date + (seconds/86400.0)

Currency

ev_type

'Y'

 

ev_width

Display width

 

ev_currency

Currency value2

Logical

ev_type

'L'

 

ev_length

0 or 1

Memo

ev_type

'M'

 

ev_wdith

FCHAN

 

ev_long

Length of memo field

 

ev_real

Offset of memo field

General

ev_type

'G'

 

ev_wdith

FCHAN

 

ev_long

Length of general field

 

ev_real

Offset of general field

Object

ev_type

'O'

 

ev_object

Object identifier

Null

ev_type

'0' (zero)

 

ev_long

Data type

1. The date is represented as a double-precision floating-point Julian day number calculated using Algorithm 199 from Collected Algorithms of the ACM. 2. The currency value is a long integer, with an implied decimal point in front of the last four digits.

Note

ev_length is the only true indicator of a string's length. The string can't have a null terminator because the string can contain embedded null characters.

Locator Structure Definition

Use the Locator structure to manipulate parameters passed by reference. The following Locator structure definition is extracted from the Pro_ext.h file:

typedef struct {
  char  l_type;
  short l_where, /* Database number or -1 for memory */
  l_NTI,      /* Variable name table offset*/
  l_offset,  /* Index into database*/
  l_subs,  /* # subscripts specified 0 <= x <= 2 */
  l_sub1, l_sub2; /* subscript integral values */
} Locator;

Locator Structure Fields

The following table is a guide to the fields in the Locator structure.

Locator field

Field use

l_type

'R'

l_where

The number of the table containing this field, or – 1 for a variable.

l_NTI

Name Table Index. Visual FoxPro internal use.

l_offset

Field number within table. Visual FoxPro internal use.

l_subs

For variables only, the number of subscripts (0 – 2).

l_sub1

For variables only, the first subscript if l_subs is not 0.

l_sub2

For variables only, the second subscript if l_subs is 2.

Note

It's good programming practice to check for the parameter type in ev_type to help determine which fields to access from the Value structure.

An Example of Accessing Parameters in an FLL Library

The following example uses _StrCpy( ) to return a Character type to Visual FoxPro that's the concatenation of its two Character parameters. Notice that although the handle of each parameter's Value structure is used as working memory to perform the concatenation, changes to this memory allocation don't affect the Visual FoxPro argument that was passed by value.

#include <Pro_ext.h>

Example(ParamBlk *parm)
{
// make the paramBlk structure easier
// to manage by using #define shortcuts
#define p0 (parm->p[0].val)
#define p1 (parm->p[1].val)

// make sure there is enough memory
if (!_SetHandSize(p0.ev_handle, p0.ev_length + p1.ev_length))
   _Error(182); // "Insufficient memory"

// lock the handles
_HLock(p0.ev_handle);
_HLock(p1.ev_handle);

// convert handles to pointers and make sure the 
// strings are null-terminated
((char *)_HandToPtr(p0.ev_handle))[p0.ev_length] = '\0';
((char *)_HandToPtr(p1.ev_handle))[p1.ev_length] = '\0';

// concatenate strings using the API function _StrCpy
_StrCpy((char *)_HandToPtr(p0.ev_handle) + p0.ev_length,
_HandToPtr(p1.ev_handle));

// return the concatenated string to Visual FoxPro
_RetChar(_HandToPtr(p0.ev_handle));

// unlock the handles
_HUnLock(p0.ev_handle);
_HUnLock(p1.ev_handle);
}

FoxInfo myFoxInfo[] = {
   {"STRCAT", Example, 2, "CC"},
};

FoxTable _FoxTable = {
   (FoxTable *) 0, sizeof(myFoxInfo)/sizeof(FoxInfo), myFoxInfo
};

See Also

Tasks

How to: Add Visual FoxPro API Calls

How to: Return Values from ActiveX Controls and FLL Libraries

Reference

Passing Parameters to Visual FoxPro API Functions

Other Resources

Accessing the Visual FoxPro API

Extending Visual FoxPro with External Libraries

API Library Construction