Safe array
In computer programming, a safe array is a data type provided in the Windows API as a handle to a dynamic array. It is also referred to by its typedef SAFEARRAY. A Component Object Model (COM) type, it was originally created as part of the OLE Automation mechanism.[1] In user code, safe arrays are primarily used to facilitate application binary interface–level interoperability between software modules, possibly written in different programming languages.[2]
Safe arrays may vary by element size, length and dimensionality, but also by the numeric index assigned to their first element, called their lower bound. This is done to support interoperability with programming languages such as Visual Basic for which zero-based indexing does not necessarily apply.[3]
Besides Microsoft Windows, the ReactOS project also includes a reimplementation of the COM safe array functionality.[4]
Struct definition
[edit]The safe array struct is defined in the Windows-specific system header file <oaidl.h>.[3]: 115
typedef struct tagSAFEARRAY {
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
PVOID pvData;
SAFEARRAYBOUND rgsabound[1];
} SAFEARRAY;
The above struct definition, in keeping with the convention of the Windows API, uses Hungarian notation on all its members, as well as using a separate "tag" name for the name of the struct itself as opposed to the typedef for the struct type.[5] The latter is a holdover from early versions of the C language, which did not permit both to have the same name.[6]
Because safe arrays are agnostic with respect to the runtime type of the element being contained, the storage size of the element type is stored in the cbElements data member, while pointer to the beginning of the actual data in the array is stored as a void pointer in pvData.[3]: 115
The safe array struct contains another struct, SAFEARRAYBOUND, which stores the size and lower bound of the array for a given dimension.
typedef struct tagSAFEARRAYBOUND {
ULONG cElements;
LONG lLbound;
} SAFEARRAYBOUND;
The dimensionality of the referent safe array is stored in the cDims data member. For each dimension of the array, there is a corresponding SAFEARRAYBOUND object in the array indicated by the rgsabound member, the count of which is indicated by the value in cDims.[3]: 115
Usage
[edit]This section needs expansion. You can help by adding missing information. (June 2026) |
The COM programming interface provides a number of APIs for managing safe arrays.[7] These functions enable programs to create, access, and destroy safe arrays of various dimensions and sizes.[3]
The safe array API exhibits ad hoc polymorphism, with the element types which a safe array can be used to store comprising a closed set as the members of the VARENUM enum type. These include many of the primitive data types available in the C++ programming language, as well as certain WinAPI structs such as VARIANT.[3]: 117 In cases where a safe array needs to contain user-defined types, the value VT_RECORD can be supplied, whereby the safe array creation function must be given an "extra" pointer to an instance of the associated IRecordInfo class. As there is no field in the SAFEARRAY handle struct itself in which this pointer may be stored, the allocator stores it in memory immediately before the struct.[4]
To create a multidimensional safe array, a program must first create and initialize an array of SAFEARRAYBOUND objects which collectively describe the dimensionality of the desired safe array. A pointer to the first element of this array can then be passed as the third and final function argument to the SafeArrayCreate function, which allocates the appropriate amount of storage for both the safe array descriptor and the array data itself.
References
[edit]- ↑ Troelsen, Andrew W. (2000). "Scriptable Objects and ATL". Developer's Workshop to COM and ATL 3.0. Texas: Wordware. pp. 445–499. ISBN 978-1-55622-704-2.
- ↑ Dicanio, Giovanni (March 2017). "Simplify Safe Array Programming in C++ with CComSafeArray". MSDN Magazine. 32 (3). Microsoft: 40–47. ISSN 1528-4859. Wikidata Q140400185.
- 1 2 3 4 5 6 Tavares, C.; Fertitta, K.; Rector, B.; Sells, C. (2007). ATL Internals: Working with ATL 8 (2nd ed.). Addison–Wesley. ISBN 978-0-321-15962-5. LCCN 2006008998. OCLC 64897677. OL 21631335M. Wikidata Q140514311.
- 1 2 Zimmer, David (September 12, 2019). "SafeArrayGetVartype". RE Corner. sandsprite.com. Retrieved July 1, 2026.
- ↑ Petzold, Charles (1988). Programming Windows: The Microsoft Guide to Programming for the MS-DOS Presentation Manager, Windows 2.0 and Windows/386. Microsoft Press. p. 30. ISBN 978-091484591-1. OL 1972517W.
- ↑ Chen, Raymond (March 26, 2008). "Why are structure names different from their typedef names?". The Old New Thing. Microsoft. Retrieved July 1, 2026.
- ↑ Fertitta, Kirk (September 2005). "Navigating the landscape of IVI". AUTOTESTCON 2005. International Automatic Testing Conference. Orlando: IEEE. pp. 801–811. doi:10.1109/AUTEST.2005.1609236. ISBN 0-7803-9101-2.