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.