xHarbour Reference Documentation > Statement Reference |
Declares a new structure in C syntax.
typedef struct [<tagName>] { ; <C Data type1> <MemberName1> ; [<C Data typeN> <MemberNameN>] ; } <StructureName> [,<rest>]
The typedef struct statement declares a new C structure class and implements it. C structures are supported in xHarbour for complete integration of non-xHarbour DLLs into an xHarbour application. Functions contained in external DLLs often require data being provided in form of structures, which is a data type that does not exist in xHarbour. The Hash() data type of xHarbour is similar to a C structure, but not identical.
Structures organize multiple data in a contiguous block of memory. Individual data is held in so called "structure members" which are comparable to instance variables of an xHarbour object. As a matter of fact, the typedef struct statement declares an xHarbour class that has the instance variables <MemberName1> to <MemberNameN>. These instance variables hold the values of structure members. A new structure object is created by specifying <StructureName> with the (struct) statement.
The typedef struct statement is intentionally modelled in C syntax to provide an xHarbour programmer with the easiest form of structure declaration: Copy & Paste. C structures are only required when an xHarbour application needs to call a function in an external DLL via DllCall(). This applies to API functions of the operating system or Third Party DLLs. If such function expects a structure as parameter, the structure declaration is provided in include files (*.H file) and can be copied into the PRG code of the xHarbour application.
Structure declaration via Copy & Paste
When a C structure declaration is copied from a *.H file into a PRG file, it must be modified so that the xHarbour preprocessor is capable of translating the typedef struct declaration. At minimum, one semicolon (;) must be added after the opening curly brace ({). This makes sure that the preprocessor recognizes the structure declaration as one line of PRG code.
After the semicolon is added, the PRG should be compiled to see if the preprocessor recognizes all <C Data type> declarations. Common C data types are listed in the #include file Wintypes.ch. Any C data type not listed in this file must be mapped to the basic C data types listed in CStruct.ch.
If a <C Data type> is not translated by the preprocessor, it is assumed to be the name of a structure that must be declared. If it is not declared, a runtime error is generated.
C strings
C data types like CHAR, TCHAR or WCHAR are declared in C syntax like an array in xHarbour. For example:
typedef struct { ; CHAR name[64] : } TESTSTRUCT
The structure member name is declared to hold 64 bytes. The C language treats this as a "byte array", while xHarbour programmers would use the data type "Character string" to represent this structure member. To reflect both "points of view", xHarbour structures provide a special object maintaining byte arrays. They have a method :asString() which returns the contents of a C byte array as an xHarbour Character string.
See also: | C Structure class, DllCall(), pragma pack(), (struct) |
Category: | C Structure support , xHarbour extensions |
Header: | cstruct.ch, winapi.ch, wintypes.ch |
Source: | rtl\cstruct.prg |
LIB: | xhb.lib |
DLL: | xhbdll.dll |
// The example demonstrates how an xHarbour structure object can // be passed to a Windows Api function. // Note that the TIME_ZONE_INFORMATION structure holds two // SYSTEMTIME structures in its members. In addition, the // StandardName and DaylightName members contain Byte arrays. #include "CStruct.ch" // required for "typedef struct" #include "wintypes.ch" // includes Windows C data types pragma pack(4) // all Windows structures are // aligned at a 4 byte boundary // structures are declared via // copy&paste from Windows SDK typedef struct _SYSTEMTIME { ; WORD wYear; // ˆ this ";" must be added WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, *PSYSTEMTIME; typedef struct _TIME_ZONE_INFORMATION { ; LONG Bias; // ˆ this ";" must be added WCHAR StandardName[32]; // member contains a byte array SYSTEMTIME StandardDate; // member contains a structure LONG StandardBias; WCHAR DaylightName[32]; SYSTEMTIME DaylightDate; LONG DaylightBias; } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION; #define DC_CALL_STD 0x0020 // calling convention for DllCall() PROCEDURE Main // creation of structure object LOCAL oTimeZone := (struct TIME_ZONE_INFORMATION) // pass structure object by reference (it is an OUT parameter) DllCall( "Kernel32.dll", DC_CALL_STD, ; "GetTimeZoneInformation", @oTimeZone ) ? "Date :" // display structure data ? "Year :", oTimeZone:standardDate:wYear ? "Month:", oTimeZone:standardDate:wMonth ? "Day :", oTimeZone:standardDate:wDay ? ? "Regular time:" ? "Hour :", oTimeZone:standardDate:wHour ? "Min. :", oTimeZone:standardDate:wMinute ? "Sec. :", oTimeZone:standardDate:wSecond ? ? "Daylight saving time:" ? "Hour :", oTimeZone:dayLightDate:wHour ? "Min. :", oTimeZone:dayLightDate:wMinute ? "Sec. :", oTimeZone:dayLightDate:wSecond ? ? "Time zone:" ? "Std. :", oTimeZone:standardName:asString() ? "Sav. ;", oTimeZone:daylightName:asString() RETURN
http://www.xHarbour.com