If it were practical to separate the code that determines the output length from the code that populates the output then you could:
- Export a function that returned the output length.
- Call that from the C# code and then allocate the output buffer.
- Call the unmanaged code again, this time asking it to populate the output buffer.
But I'm assuming that you have rejected this option because it is impractical. In which case your code is a perfectly reasonable way to solve your problem. In fact I would say that you've done a very good job.
The code will work just the same in x86 once you fix the calling convention mismatch. On the C++ side the calling convention is cdecl
, but on the C# side it is stdcall
. That doesn't matter on x64 since there is only one calling convention. But it would be a problem under x86.
Some comments:
- You don't need to use
[Out]
as well asout
. The latter implies the former. - You can avoid exporting the deallocator by allocating off a shared heap. For instance
CoTaskMemAlloc
on the C++ side, and then deallocate withMashal.FreeCoTaskMem
on the C# side.