Compartir a través de


Transmitir y recibir parámetros

Cuando Visual FoxPro llama al programa del usuario, éste puede recibir parámetros. Por ejemplo, un control ActiveX puede recibir parámetros cuando se llama a uno de sus métodos. De forma similar, un programa de Visual FoxPro puede llamar a una función de la biblioteca FLL y pasarle parámetros.

Visual FoxPro puede transferir parámetros al programa del usuario por valor o por referencia. De forma predeterminada, los parámetros respetan la configuración realizada con SET UDFPARMS. Otras variables (como matrices o campos) y expresiones se pasan por valor.

Para obligar a que un parámetro se pase por referencia, tiene que usar como prefijo de la referencia de variable el operador @. Para forzar la transferencia por valor de un parámetro, inclúyalo entre paréntesis.

Nota   En Visual FoxPro, los elementos de matriz individuales siempre se pasan por valor. Cuando SET UDFPARMS se establece en VALUE y no se especifica ningún elemento de matriz, el nombre de matriz se refiere al primer elemento de la matriz (a no ser que tenga el prefijo @).

Como los controles ActiveX y los objetos COM son programas estándar de Windows, no es necesario ningún mecanismo especial para transferir parámetros entre Visual FoxPro y el programa del usuario. Puede escribir el programa como si estuviera recibiendo parámetros desde cualquier programa escrito en C o C++.

En contraste, las funciones de una biblioteca FLL usan la estructura FoxInfo para recibir datos desde Visual FoxPro. La estructura FoxInfo muestra sus funciones de biblioteca y el número y tipo de parámetros que esperan. Por ejemplo, la siguiente estructura FoxInfo pertenece a una biblioteca con una función, internamente llamada dates, que acepta un parámetro Character:

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

Las funciones que defina en sus bibliotecas reciben realmente un único parámetro: un puntero al bloque de parámetros. Este bloque de parámetros, definido en la estructura ParamBlk, guarda toda la información acerca de los parámetros que se pasaron en la llamada de función de Visual FoxPro. La declaración de función tiene el siguiente formato:

void function_name(ParamBlk *parm)

Por ejemplo, la definición de función para dates es:

void dates(ParamBlk *parm)

La estructura de ParamBlk se compone de un entero que representa el número de parámetros, seguido inmediatamente por una matriz de uniones de parámetros. La definición de estructura se incluye en 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;

El parámetro typedef incluido en la estructura ParamBlk es una unión de una estructura Value y una estructura Locator. La llamada por valor se controla mediante una estructura Value; la llamada por referencia se controla mediante una estructura Locator. Estas estructuras se usan para tener acceso a parámetros pasados a la función del usuario cuando Visual FoxPro la llama.

La siguiente información sale del archivo Pro_ext.h y muestra la definición del tipo Parameter:

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

Definir la estructura Value

Si se pasa por valor un parámetro a la función, use la estructura Value para tener acceso al mismo. La siguiente definición de estructura Value se extrae del archivo Pro_ext.h:

// 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;

Campos de la estructura Value

La siguiente tabla es una guía para los valores que puede pasar a la estructura Value y recibir de ésta para distintos tipos de datos. Sólo los campos de la estructura mostrados para un tipo de datos se usan para ese tipo de datos.

Contenido de una estructura Value para distintos tipos de datos

Tipo de datos Campo de estructura Valor
Character
ev_type
‘C’
 
ev_length
longitud de cadena
 
ev_handle
MHANDLE a cadena
Numeric
ev_type
‘N’
 
ev_width
Ancho de presentación
 
ev_length
Posiciones decimales
 
ev_real
Precisión doble
Integer
ev_type
‘I’
 
ev_width
Ancho de presentación
 
ev_long
Entero largo
Date
ev_type
‘D’
 
ev_real
Fecha1
Date Time
ev_type
‘T’
 
ev_real
Fecha + (segundos/86400.0)
Currency
ev_type
‘Y’
 
ev_width
Ancho de presentación
 
ev_currency
Valor2 de tipo Currency
Logical
ev_type
‘L’
 
ev_length
0 ó 1
Memo
ev_type
‘M’
 
ev_wdith
FCHAN
 
ev_long
Longitud de campo memo
 
ev_real
Desplazamiento de campo memo
General
ev_type
‘G’
 
ev_wdith
FCHAN
 
ev_long
Longitud de campo general
 
ev_real
Desplazamiento de campo general
Object
ev_type
‘O’
 
ev_object
Identificador de objeto
Null
ev_type
‘0’ (cero)
 
ev_long
Tipo de datos

1. La fecha está representada como un número de día Juliano de coma flotante de doble precisión calculado mediante el algoritmo 199 de Collected Algorithms de la ACM.
2. El valor de tipo Currency es un entero largo, con una coma decimal implícita delante de los cuatro últimos dígitos.

Nota   ev_length es el único indicador verdadero de la longitud de una cadena. La cadena no puede tener un terminador nulo porque no puede contener caracteres nulos incrustados.

Definir la estructura Locator

Use la estructura Locator para manipular parámetros pasados por referencia. La siguiente definición de estructura Locator se extrae del archivo Pro_ext.h:

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;

Campos de estructura Locator

La tabla siguiente es una guía acerca de los campos de la estructura Locator.

Campo Locator Uso del campo
l_type
'R'
l_where
Número de tabla que contiene este campo, o – 1 para una variable.
l_NTI
Índice de tabla de nombres. Uso interno de Visual FoxPro.
l_offset
Número de campo de tabla. Uso interno de Visual FoxPro.
l_subs
Sólo para variables, el número de subíndices (0 – 2).
l_sub1
Sólo para variables, el primer subíndice si l_subs no es 0.
l_sub2
Sólo para variables, el segundo subíndice si l_subs es 2.

Nota   Es una buena práctica de programación comprobar el tipo de parámetro de ev_type para ayudarle a determinar a qué campos se tiene acceso desde la estructura Value.

Un ejemplo de parámetros de acceso a una biblioteca FLL

El siguiente ejemplo usa StrCpy( ) para devolver a Visual FoxPro un tipo Character que es la concatenación de sus dos parámetros Character. Observe que aunque el controlador de la estructura Value de cada parámetro se usa como memoria de trabajo para realizar la concatenación, los cambios a esta asignación de memoria no afectan al argumento de Visual FoxPro que se ha pasado por valor.

#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
};

Vea también

Agregar llamadas a la API de Visual FoxPro | Devolver un valor a Visual FoxPro | Acceso a la API de Visual FoxPro | Transferir parámetros a funciones de la API de Visual FoxPro | Ampliar Visual FoxPro con bibliotecas externas | Creación de bibliotecas API