When I described how SafeÂArrayÂAddÂRef keeps its reference count in a side table, commenter Koro Unhallowed wondered why we couldn’t store the reference count either before or after the formal SAFEARRAY structure. Commenter Peter Cooper Jr. suspected that there might be cases where applications assumed how much memory a SAFEARRAY occupied.
And indeed that is the case.
Not all SAFEARRAYs are created by the SafeÂArrayÂCreate function. I’ve seen code that declared and filled out their own SAFEARRAY structure. In those cases, the code allocates exactly sizeof(SAFEARRAY) bytes and doesn’t allocate any bonus data for the reference count.
Indeed, there three flags in the fFeatures member for these “bring your own SAFEARRAY” structures.
FADF_AUTO |
An array that is allocated on the stack. |
FADF_STATIC |
An array that is statically allocated. |
FADF_EMBEDDED |
An array that is embedded in a structure. |
These flag indicate that the array was not created by SafeÂArrayÂCreate but rather was constructed manually by the caller in various ways.¹
Note that if you pass a SAFEARRAY with one these flags to SafeÂArrayÂAddÂRef, it will still increment the reference count, but you don’t get a data pointer back because the caller does not control the lifetime of the SAFEARRAY. The lifetime of the SAFEARRAY is controlled by the lifetime of the SAFEARRAY variable on the stack (FADF_AUTO), in the DLL’s global data segment (FADF_STATIC), or in the enclosing object (FADF_EMBEDDED).
This means that our earlier suggestion to wrap the SAFEARRAY inside an in/out VARIANT runs into trouble if the SAFEARRAY is one of these types of arrays with externally-controlled lifetime. For those, you have no choice but to copy the data.
¹ The documentation is, however, ambiguous about what “the array” refers to. Is it referring to the SAFEARRAY structure itself? Or is it referring to the data pointed to by the pvData member?
0 comments
Be the first to start the discussion.