Übergeben und Empfangen von Parametern
Wenn Ihr Programm aus Visual FoxPro aufgerufen wird, kann es Parameter empfangen. Ein ActiveX-Steuerelement kann z. B. Parameter empfangen, wenn eine seiner Methoden aufgerufen wurde. Ganz ähnlich kann ein Visual FoxPro-Programm eine Funktion Ihrer FLL-Bibliothek aufrufen und Parameter an diese übergeben.
Visual FoxPro kann Parameter an Ihr Programm als Wert oder als Verweis übergeben. Standardmäßig wird für Parameter die Einstellung beachtet, die mit SET UDFPARMS vorgenommen wurde. Andere Parameter (z. B. Arrays oder Felder) sowie Ausdrücke werden als Wert übergeben.
Wenn Sie die Übergabe eines Parameters als Verweis erzwingen möchten, dann stellen Sie dem Parameterverweis den @-Operator voran. Wenn Sie die Übergabe eines Parameters als Wert erzwingen möchten, dann geben Sie ihn in runden Klammern an.
Anmerkung In Visual FoxPro werden einzelne Elemente eines Arrays immer als Wert übergeben. Wenn SET UDFPARMS auf VALUE eingestellt und kein Array-Element angegeben ist, verweist der Array-Name selbst auf das erste Element des Arrays (sofern er nicht das Präfix @ hat).
Da ActiveX-Steuerelemente und COM-Objekte Windows-Standardprogramme sind, ist kein spezieller Mechanismus erforderlich, um Parameter aus Visual FoxPro sowie aus Ihrem Programm zu übergeben. Sie können das Programm so schreiben, als würde es Parameter von einem beliebigen C- oder C++-Programm empfangen.
Im Gegensatz dazu verwenden die Funktionen einer FLL-Bibliothek die Struktur FoxInfo, um Daten von Visual FoxPro zu empfangen. In der Struktur FoxInfo sind Ihre Bibliotheksfunktionen sowie die Anzahl und Typen der Parameter aufgelistet, die diese erwarten. Die folgende FoxInfo
-Struktur gehört beispielsweise zu einer Bibliothek mit einer Funktion, die intern den Namen datum
hat und einen Parameter des Typs Zeichen (Character) entgegennimmt:
FoxInfo myFoxInfo[] = {
{ "DATES", (FPFI) dates, 1, "C" }
};
Eine Funktion, die Sie in Ihrer Bibliothek definieren, empfängt tatsächlich nur einen Parameter: einen Zeiger auf den Parameterblock. Dieser Parameterblock, der in der Struktur ParamBlk
definiert ist, enthält alle Informationen über die Parameter, die von dem jeweiligen Visual FoxPro-Funktionsaufruf übergeben wurden. Ihre Funktionsdeklaration muss dem folgenden Format entsprechen:
void function_name(ParamBlk *parm)
Die Funktionsdefinition für datum
lautet beispielsweise:
void dates(ParamBlk *parm)
Die Struktur ParamBlk
besteht aus einer ganzen Zahl, die die Anzahl der Parameter repräsentiert, gefolgt von einem Array aus Parameterverbunden (Unions). Die Strukturdefinition ist in Pro_ext.h enthalten:
/* A parameter list to a library function. */
typedef struct {
short int pCount; /* number of parameters passed */
Parameter p[1]; /* pCount parameters */
} ParamBlk;
Die Typdefinition (typedef) Parameter
, die Teil der Struktur ParamBlk
ist, ist ein Verbund (union) aus einer Value- und einer Locator-Struktur. Aufrufe mit Wertübergabe werden von einer Value-Struktur verwaltet, Aufrufe mit Verweisübergabe von einer Locator-Struktur. Mit diesen Strukturen greifen Sie auf die Parameter zu, die an Ihre Funktion übergeben werden, wenn die Funktion in Visual FoxPro aufgerufen wird.
Die folgenden Informationen sind der Datei Pro_ext.h
entnommen und zeigen die Definition des Typs Parameter
:
/* A parameter to a library function. */
typedef union {
Value val;
Locator loc;
} Parameter;
Die Definition der Struktur "Value"
Wird ein Parameter als Wert an Ihre Funktion übergeben, greifen Sie mit der Struktur Value darauf zu. Die folgende Value
-Strukturdefinition ist der Datei Pro_ext.h entnommen.
// 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;
Die Felder der Struktur "Value"
Die folgende Tabelle bietet eine Übersicht über die Werte, die Sie für unterschiedliche Datentypen in der Struktur Value übergeben bzw. empfangen können. Für die aufgeführten Datentypen werden nur jeweils die Felder der Struktur verwendet, die bei dem jeweiligen Datentyp angegeben sind.
Inhalt der Struktur "Value" bei unterschiedlichen Datentypen
Datentyp | Feld der Struktur | Wert |
---|---|---|
Zeichen |
|
'C' |
|
Länge der Zeichenfolge | |
|
MHANDLE für Zeichenfolge | |
Numerisch |
|
'N' |
|
Anzeigebreite | |
|
Dezimalstellen | |
|
Doppelte Genauigkeit (double) | |
Integer |
|
'I' |
|
Anzeigebreite | |
|
Lange Ganzzahl (long) | |
Datum |
|
'D' |
|
Datum1 | |
DatumZeit |
|
'T' |
|
Datum + (Sekunden/86400.0) | |
Währung |
|
'Y' |
|
Anzeigebreite | |
|
Währungswert2 | |
Logisch |
|
'L' |
|
0 oder 1 | |
Memo |
|
'M' |
|
FCHAN | |
|
Länge des Memofeldes | |
|
Versatz (Offset) des Memofeldes | |
Objektfeld |
|
'G' |
|
FCHAN | |
|
Länge des Objektfeldes | |
|
Versatz (Offset) des Objektfeldes | |
Objekt |
|
'O' |
|
Objektbezeichner | |
Null |
|
'0' (Null) |
|
Datentyp |
1. Das Datum ist als Julianische Tageszahl formuliert, die eine doppeltgenaue Gleitkommazahl (double) ist und mit dem Algorithmus 199 aus Collected Algorithms des ACM berechnet wurde.
2. Ein Währungswert ist eine lange Ganzzahl (long) mit einem impliziten Dezimalkomma vor den letzten vier Ziffern.
Anmerkung
ev_length
ist der einzige echte Indikator für die Länge einer Zeichenfolge. Die Zeichenfolge darf nicht mit einem Nullzeichen abgeschlossen sein, da sie eingebettete Nullzeichen enthalten kann.
Die Definition der Struktur "Locator"
Mit der Struktur Locator verwalten Sie Parameter, die als Verweis übergeben werden. Die folgende Locator
-Strukturdefinition ist der Datei Pro_ext.h entnommen.
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;
Die Felder der Struktur "Locator"
Die nachstehende Tabelle ist ein Wegweiser für die Felder der Struktur Locator.
Locator-Feld | Verwendung des Feldes |
---|---|
|
'R' |
|
Die Nummer der Tabelle, die dieses Feld enthält, oder -1 für eine Variable. |
|
Namenstabellenindex. Visual FoxPro-interne Verwendung. |
|
Feldnummer innerhalb der Tabelle. Visual FoxPro-interne Verwendung. |
|
Nur für Variablen: die Anzahl der Indizes (0-2). |
|
Nur für Variablen: der erste Index, wenn l_subs ungleich 0 ist. |
|
Nur für Variablen: der zweite Index, wenn l_subs gleich 2 ist. |
Anmerkung Es ist ein guter Programmierstil, den Parametertyp in
ev_type
zu überprüfen, um entscheiden zu können, auf welche Felder der Struktur Value zugegriffen werden soll.
Ein Beispiel für den Zugriff auf Parameter einer FLL-Bibliothek
Im folgenden Beispiel wird mit _StrCpy( )
ein Zeichentyp an Visual FoxPro zurückgegeben, der die Verkettung der beiden Zeichen-Parameter der Funktion ist. Obwohl das Handle der Value-Struktur jedes Parameters als Arbeitsspeicher für die Verkettung verwendet wird, wirken sich Änderungen dieser Speicherzuweisung nicht auf das Visual FoxPro-Argument aus, das als Wert übergeben wurde.
#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
};
Siehe auch
Hinzufügen von Visual FoxPro-API-Aufrufen | Rückgabe eines Wertes an Visual FoxPro | Zugreifen auf die Visual FoxPro-API | Übergeben von Parametern an Visual FoxPro-API-Funktionen | Erweitern von Visual FoxPro mit externen Bibliotheken | Erstellung der API-Bibliothek