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 |
|
‘C’ |
|
longitud de cadena | |
|
MHANDLE a cadena | |
Numeric |
|
‘N’ |
|
Ancho de presentación | |
|
Posiciones decimales | |
|
Precisión doble | |
Integer |
|
‘I’ |
|
Ancho de presentación | |
|
Entero largo | |
Date |
|
‘D’ |
|
Fecha1 | |
Date Time |
|
‘T’ |
|
Fecha + (segundos/86400.0) | |
Currency |
|
‘Y’ |
|
Ancho de presentación | |
|
Valor2 de tipo Currency | |
Logical |
|
‘L’ |
|
0 ó 1 | |
Memo |
|
‘M’ |
|
FCHAN | |
|
Longitud de campo memo | |
|
Desplazamiento de campo memo | |
General |
|
‘G’ |
|
FCHAN | |
|
Longitud de campo general | |
|
Desplazamiento de campo general | |
Object |
|
‘O’ |
|
Identificador de objeto | |
Null |
|
‘0’ (cero) |
|
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 |
---|---|
|
'R' |
|
Número de tabla que contiene este campo, o – 1 para una variable. |
|
Índice de tabla de nombres. Uso interno de Visual FoxPro. |
|
Número de campo de tabla. Uso interno de Visual FoxPro. |
|
Sólo para variables, el número de subíndices (0 – 2). |
|
Sólo para variables, el primer subíndice si l_subs no es 0. |
|
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