Commands and Statements

Command STRUCTURE | UNION Foundation

Defines a structure or union

Syntax
STRUCTURE <cName> [PACK <nPackSize>] 
   VAR <VarName> AS [@][STRUCTURE|UNION] <VarType>[<nArrayLen>]
ENDSTRUCTURE
UNION <cName> [PACK <nPackSize>] 
   VAR <VarName> AS [@][STRUCTURE|UNION] <VarType>[<nArrayLen>]
ENDUNION
Parameters
<cName>
The name of the structure or union that is being defined. Structure and union names follow the same convention as symbol names. They must begin with an underscore or a letter and must contain alpha numeric characters. The first 255 characters are significant.
<nPackSize>
The optional PACK clause specifies the alignment of the structure or union members in the computer's memory. To do this, the Byte boundary the structure or union is allowed to be packed to must be specified in <nPackSize>.
Description

Structures are used to represent structured data in a way allowing the data to be exchanged with operating system APIs or DLL functions using the EXTERN command. The declaration of a structure begins with the statement STRUCTURE. Following the structure name is the declaration of the structure members. The structure declaration ends with the statement ENDSTRUCTURE.

A union is a special case of a structure allowing to map different data items to the same location in memory. Which kind of data is actually stored in the union depends on the respective use-case. The application can access the data in the union through one of the union's members, allowing the application to work with the data using the data type valid for the current use-case. The declaration of a union begins with a UNION and ends with an ENDUNION statement.

Defining structure and union members

Structure and union members are declared using one or more statements of the form:

VAR <VarName> AS [@][STRUCTURE|UNION] <VarType>[<nArrayLen>] 

Each member has a unique name defined via <VarName>, and a data type defined via <VarType>. The data type must be set to a key word identifying a parameter type of a DLL function as documented for the EXTERN command. For example, UINTEGER or STRING.

For members whose value is an array (field), the optional <nArrayLen> specifier must be used for reserving sufficient space in the structure or union. In this case, <VarType> specifies the base type of the array elements. Note that specifying an array length is only valid if the value of the member is stored directly within the structure or union.

If a member's value is not stored directly in the structure or union but is accessed via a reference to a certain memory location (pointer), the member's data type must be prefixed with the reference operator (@).

Structures and unions are complex data types and can themselves be defined as members of a structure or union. To do this, the keyword STRUCTURE or UNION must be included in the declaration of the respective member followed by the structure or union name,

Examples:

VAR nId   AS UINTEGER       // Member is an unsigned integer 
VAR lFlag AS BOOL           // Member is a 32 bit boolean 
VAR cName AS STRING[32]     // Member is a string of up to 32 characters 
VAR oRect AS STRUCTURE RECT // Member is a RECT structure instance 

Creating structure instances

Structure instances are created implicitly from a structure or union declaration by declaring a LOCAL variable of the corresponding type. See the LOCAL statement for syntax and usage information.

Using external memory for initializing structures

The method :setAddress( <nPointer> ) can be used for setting the memory address of a structure instance.

Getting the size of a structure or union

The Byte size a structure or union occupies in memory can be determined by executing the :sizeOf() method on the structure or union instance.

Data type of a structure instance

Structure instances expose themselves as objects to the application. Consequently, the ValType() function returns the data type "O" (object) when called with a structure instance.

Examples
Declaring and creating a STRUCTURE instance
// The following example demonstrates declaring a RECT structure 
// and creating an instance of the structure in a LOCAL variable. 
// The structure instance is then passed to the GetWindowRect() 
// Win32 API function via the EXTERN command. 
// 
// NOTE: The example must be compiled and linked in GUI (PM) mode. 
// Example: xpp /b sample.prg /link:"/pm:pm /de"<ENTER> 
#include "dll.ch" 

// Structure declaration 
STRUCTURE RECT 
   VAR left   AS INTEGER 
   VAR top    AS INTEGER 
   VAR right  AS INTEGER 
   VAR bottom AS INTEGER 
ENDSTRUCTURE 

EXTERN INTEGER GetWindowRect( nhWnd AS UINTEGER, @lpRect AS STRUCTURE ) IN WIN32API 

PROCEDURE Main() 
   // Create a RECT instance in a LOCAL variable 
   LOCAL oRect AS STRUCTURE RECT 
   LOCAL nHwnd 

   nHwnd := SetAppWindow():getHwnd() 

   // Call the GetWindowRect() API which fills members 
   // of a RECT structure with the on-screen coordinates 
   // of a window 
   GetWindowRect( nHwnd, @oRect ) 

   ? "The application window's rectangle is: {" + ; 
      Var2Char(oRect:left) + "," +; 
      Var2Char(oRect:top)  + "," +; 
      Var2Char(oRect:right)+ "," +; 
      Var2Char(oRect:bottom) + "}" 
   WAIT 
RETURN 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.