Marshaling an array as a return value?
How do you marshal an array as a return value? What marshalling attributes must be specified?
Specifically, using COM Interop, I want to use an interface member that returns an array. The implementation of this interface is written using an unmanaged object and a COM style interface.
In C#, the interface declaration would look like this:
public interface IMyInterface
{
int[] MyArray
{
get;
}
}
In unmanaged COM interface land, the property get function looks like this:
struct IMyInterface : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE get_MyArray( int** array, int* size );
// array is an "out" parameter, a pointer to an array of integers
// size is an "out" parameter, and returns the number of elements in the array.
};
How do I provide marshalling attributes on the MyArray property get declaration such that I can call this function?
If it's not directly possible, then I am willing to make some compromises:
1) I'm prepared to accept a method declaration in the c# interface declaration, rather than a property get. Like this:
int[] MyArray();
2) I'm prepared to rewrite the implementation of the get_MyArray unmanaged function
3) I'm prepared to modify the signature of the unmanaged function. For example, I'm okay if it has to look like this:
virtual HRESULT STDMETHODCALLTYPE get_MyArray( int* size, SOMETHING<SOMETHINGELSE>* array );
3) I'm prepared to allocate the array in the implementation using CoTaskMemAlloc or whatever memory allocation necessary.
Some details on which I am NOT willing to compromise:
1) The array must be a return value in C#. I am NOT prepared to change the IMyInterface method to this:
void MyArray( out int[] array, out int size );
2) I do not want to take additional marshalling steps in the caller. So I don't want to have to call:
Marshal.FreeCoTaskMem()
3) The size of the array must be variable, in that it must not a constant size in the marshalling attributes. The returned array, could contain any number of elements.
Here's something I tried that did not work:
public interface IMyInterface
{
int[] MyArray
{
[ return : MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1) ]
get;
}
}
I get the following error:
An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in Test.exe
Additional information: Can not marshal return value.

