As mentioned above, a GDD can describe an n-dimension array. The user can describe the bounds of the n-dimensional array. To facilitate the use of large, and perhaps shared data arrays, a GDD allows a user to store a reference to an array of data. In addition, a destructor function can be registed in the GDD to inform the owner of the data array when the GDD referencing the data goes away. The purpose of the destructor function is to delete the array of data, since the GDD does not know what to do with referenced data.
To manage GDDs in a multi-tasking system or a system that uses many layers of software, GDDs implement reference counting. With reference counting, only one copy of GDD can be shared by many subsystems. The GDD creator function can pass it to many other functions without worrying about deleting it, when the last function using the GDD requests that it be destroyed does it really go away.
As menitioned above, a GDD allows the user to describe the data in terms of the application. This is done by the user by assigning an arbitrary integer identifier to a GDD. The user places a meaning on the identifiers such as 1=high-alarm-limit, 2=low-alarm-limit. This identifier is termed application type. A second component of the GDD library known as the Application Type Table is used to manage the application type identifiers. Application type values are registered in the table along with a text string and optionally a prototype GDD. The prototype GDD can be a container GDD. The table allows users to retreive GDDs of a specific application type.
A GDD describe and manages a piece of data using the following information:
The GDD library is a C++ class library and therefore requires using the C++ compiler.
All GDDs must be created dynamically, a GDD cannot be created on the stack as a local variable. The gdd class forbids the user from deleting the gdd. In order for referencing counting to work correctly the user must "unreference" the gdd instance instead of delete it. The gdd class does take over the memory management routines for itself and all it's subclass. This means that you are not using the malloc()/free() memory management when GDDs are created and destroyed. It is important to remember that since reference counting is used, a GDD passed into a function must be referenced before the function returns if the GDD is to be kept for longer then the running of that function. In other words, if you are creating a library function "add" that records process variable names in a linked list, and the process variable names are passed to you as GDDs, then you must reference the GDD since the linked list exists after the return of the "add" function. If you are creating a GDD, you must unreference it when you are finished with it, even it you have passed it into other library functions. Generalizing on this, it is the responsibility of the GDD creator or GDD referencer to unreference the GDD instance when they are finished with it.
aitInt8 8 bit character aitUint8 8 bit unsigned character aitInt16 16 bit short aitUint16 16 bit unsigned short aitEnum16 16 enumerated value aitInt32 32 bit integer aitUint32 32 bit unsigned integer aitFloat32 32 bit floating point number aitFloat64 64 bit floating point number aitPointer Standard pointer aitIndex 32 bit index value aitStatus 32 bit unsigned integer for status value aitFixedString 40 byte string of characters aitString Variable length string data type aitTimeStamp Two 32 bit integers describing time (seconds/nanoseconds)These data types should be used whenever possible to prevent problems when compiling programs for different architectures. Most of they data types are enumerated as descrived above for use as a primitive type code. The enumerated names are just the above type names with the word "Enum" inserted after "ait". It should be noted that aitTimeStamp is not a standard primitive type.
typedef enum {
aitEnumInvalid=0,
aitEnumInt8,
aitEnumUint8,
aitEnumInt16,
aitEnumUint16,
aitEnumEnum16,
aitEnumInt32,
aitEnumUint32,
aitEnumFloat32,
aitEnumFloat64,
aitEnumFixedString,
aitEnumString,
aitEnumContainer
} aitEnum;
The enumerated type code allows a user to dynamically convert from one
type to another. The AIT portion of the GDD library contains a large
primitive type conversion matrix. The conversion matrix is indexed by
the source and destination enumeration type codes. The matrix is a
Several important issues related to where the actual data is stored must be remembered when using GDDs: