Caller provides memory and function fails if there is to little memory, but writes the the required (variable) amount of memory to an `out length` pointer.
Effectively leading to a common pattern of:
1. call function with empty buffer (or buffer or arbitrary size)
2. allocate buffer
3. call function again with properly sized buffer
4. add a loop if between 1 & 3 the required buffer size can change
its fascinating how well it works for some of it's common use cases and how subtle but badly broken it can be for other use cases :=)