I am currently working on the documentation of the Windows Media Format SDK, and I was confronted with some API's which accept variable sized structs in the DRM Client Extended API. Writing clean memory allocation code for variable structs can be a painful endeavour and I am a lazy lazy man. For my own purposes I developed the a data structure which simplifies usage of data structures with variable sized fields when the size is a constant known at compile-time.
The following code demonstrates how you can write a simple template wrapper around an arbitrary variable sized struct (where the last field of the struct is variable sized).
// Pre-declaration
typedef unsigned int DWORD;
typedef unsigned char BYTE;
// This is an actual struct from the WMF SDK
struct WMDRM_IMPORT_CONTENT_KEY
{
DWORD dwVersion;
DWORD cbStructSize;
DWORD dwIVKeyType;
DWORD cbIVKey;
DWORD dwContentKeyType;
DWORD cbContentKey;
BYTE rgbKeyData[ 1 ];
};
// This is a somewhat generic template wrapper around a variable sized struct.
template<typename Struct, int FieldSize_N>
struct VarStruct
{
Struct* operator->() { return &(data_union.as_struct); }
static const int field_size = FieldSize_N;
static const int struct_size = sizeof(Struct) + FieldSize_N - 1;
private:
union
{
Struct as_struct;
BYTE as_array[struct_size];
}
data_union;
};
// Here is some mundane usage.
int main()
{
VarStruct<WMDRM_IMPORT_CONTENT_KEY, 42> vs;
for (int i=0; i < 42; ++i)
{
vs->rgbKeyData[i] = i;
}
}
I hope this code is self-explanatory, and can come in useful. Feel free to fire any questions my way.
The contents of this post are licensed under the Creative Commons Attribution-NonCommercial-NoDerivs license. The opinions in this post are my own and are not neccessarily the views of my employer, Microsoft.