Wenn man in Tabellen einen Fremdschlüssel benötigt und nicht den Datentyp Integer (AutoInc) verwenden möchte oder kann (z.B. wegen einer ODBC-Verbindung mit VFP6 Treiber), oder wenn man mit mehreren Rechnern in einem gemeinsam Verzeichnis im Netzwerk temporäre Dateinamen generieren will, die mit Sicherheit eindeutig sind, stößt man mit SYS(2015) rasch an die Grenzen, weil das Ergebnis immer nur auf dem jeweiligen Rechner eindeutig ist. Als Alternative kann man einen sogenannten GUID (Globally Unique Identifier) verwenden.
Sie kennen sicherlich diese unansehnlichen "Würste" von Zahlen und Buchstaben in geschwungenen Klammern aus der Windows Registry, Ihrem temporären Verzeichnis oder aus dem OLE-Control / ActiveX Dialog von FoxPro:
{951AB756-D4FB-446f-BB29-63C896E316A0}
GUIDs sind die Microsoft-spezifische Implementierung der sogenannten UUIDs (Universally Unique Identifier), sind 128 Bit lang und garantieren die Eindeutigkeit über Ort und Zeit, das heißt, es ist sicher gestellt, dass eine einmal generierte GUID nirgends und zu keinem Zeitpunkt ein zweites Mal generiert werden kann. Diese UUIDs wurden ursprünglich von Apollo Computers eingesetzt und später in das Open Software Foundation DCE (Distributed Computing Environment) übernommen. Prinzipiell werden sie basierend auf der Systemzeit und der Adresse einer Netzwerkkarte generiert. Eine genaue Beschreibung findet sich im RFC 4122 vom Juli 2005.
Die obige Darstellungsform ist die Repräsentation einer GUID als Zeichenfolge, im Speicher belegt ein GUID genau 16 Byte (16 * 8 Byte = 128 Bit).
Das Windows API (Application Programmer Interface) stellt in
der Bibliotheksdatei ole32.dll eine Funktion zur Verfügung, mit der eine
GUID generiert werden kann:
Um sie in FoxPro nutzen zu können, müssen wir sie zunächst einmal deklarieren. Bitte beachten Sie dabei, dass die Groß-/Kleinschreibung des Funktionsnamens genau eingehalten werden muss:
DECLARE Integer CoGreateGuid ; IN ole32.dll ; String@ pguid
pguid ist dabei eine Referenz auf einen 16 Byte langen
Speicherbereich, in den die Funktion den 128 Bit langen GUID schreibt. Am
einfachsten erstellen wir in FoxPro einen Speicherbereich bestimmter Länge mit
der Funktion
lcGuid = SPACE(16) CoCreateGuid(@lcGuid)
Die Funktion
Rückgabewert | Bedeutung |
---|---|
0 (0x00000000) | Die Funktion wurde erfolgreich ausgeführt. Im Speicher, den wir als Referenz übergeben haben, befinden sich nun 16 Byte, die eine GUID darstellen. Jedes dieser 16 Byte kann dabei für sich einen Wert zwischen 0 und 255 aufweisen. |
2147485472 (0x80000720) | Die generierte GUID ist nur auf diesem Computer eindeutig. Es kann sein, dass ein anderer Computer ebenfalls diese GUID generiert. |
2147485387 (0x800006CB) | Für diesen Computer kann keine Hardware Adresse (Ethernet oder Token-Ring) ermittelt werden. |
Da ein jedes der 16 Byte in lcGuid nun einen Wert zwischen 0 und 255 aufweisen kann, aber nicht alle diese Werte am Bildschirm oder Drucker als Zeichen ausgegeben werden können (die Zeichen 0-31 und 127 sind reservierte Steuerzeichen), können wir diese "Zeichenfolge" nur in Tabellenfeldern verwenden, die ausdrücklick binäre Daten unterstützen, z.B. Character (binary), Memo (binary), oder Varbinary.
Um die zuvor generierten 16 Byte in eine druckbare Zeichenfolge
umzuwandeln (dieses "seltsame" Ding in den geschwungenen Klammern), kann man sich der
Windows API Funktion
DECLARE Integer StringFromGUID2 ; IN ole32.dll ; String pguid, ; String @lpszBuffer, ; Integer cbBuffer
Diese Funktion erwartet drei Parameter:
pguid ist
dabei der Speicherbereich, den wir zuvor mit
lpszBuffer ist die Referenz auf einen Speicherbereich, der groß genug sein muss, um die resultierende Zeichenfolge aufnehmen zu können. Dabei ist aber zu beachten, dass nicht nur die bei Windows API Funktionen übliche Nullterminierung (C/C++ String) eingerechnet werden muss, sondern es ist auch noch eine Besonderheit dieser Funktion, dass sie die Zeichenfolge nicht als ANSI Zeichen (1 Byte pro Zeichen) zurück gibt, sondern als UNICODE, also zwei Byte pro Zeichen. Der Speicherbereich muss demnach zumindest 2*(38+1) = 78 Byte lang sein.
cbBuffer gibt der Funktion die Länge des Speicherbereiches lpszBuffer an. Aber Achtung: Da lpszBuffer mit UNICODE Zeichen gefüllt wird, muss auch hier die Länge in UNICODE Zeichen angegeben werden, also Anzahl der Bytes / 2.
Wenn cbBuffer größer als 38 ist, gibt die Funktion 39 zurück, das ist die Anzahl der UNICODE-Zeichen einschließlich der Nullterminierung. Wenn cbBuffer kleiner als 38 ist, der Speicherbereich also nicht ausreichen würde, gibt die Funktion 0 zurück.
lcBuffer = SPACE(78) lnResult = StringFromGUID2(lcGuid,@lcBuffer,LEN(lcBuffer)/2)
Abschließend müssen wir mit
lcBuffer = LEFT(lcBuffer,(lnResult-1)*2) lcBuffer = STRCONV(lcBuffer,6)
Sie können das folgende Beispielprogramm herunterladen, in dem alle diese grundsätzlichen Schritte demonstriert werden. Es enthält eine Funktion GuidGen, die Sie auch in eigene Anwendungen übernehmen können.
guidgen.zip (2
kB)
Die folgenden Dokumente stehen nur dFPUG Mitgliedern zur Verfügung. Weitere Informationen zur Mitgliedschaft finden Sie hier.