[Mono-dev] Problem with Marshing c arrays as UnmanagedType.LPArray using SizeParamIndex when doing Native -> Managed COM method calls.
Tom Hindle
tom_hindle at sil.org
Fri Jun 12 12:59:40 EDT 2009
Hi,
I have implement a Managed class which implements
System.Runtime.InteropServices.ComTypes.IStream (defined in
mcs/class/corlib/System.Runtime.InteropServices.ComTypes/IStream.cs)
When I attempt to use IStream.Write from C++ I get a
System.Runtime.InteropServices.MarshalDirectiveException: Array size
control parameter must be an integral type.
IStream's Write method is Marshaled as:
void Write ([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
byte[] pv, int cb, IntPtr pcbWritten);
(which is correct : cb is an int)
Looking at the function emit_marshal_array in marshal.c in the
MARSHAL_ACTION_MANAGED_CONV_IN case section:
When checking param index type (which is 1 as SizeParamIndex == 1)
(about line 6778) the Array itself is being checked (byte[] pv) as
m->sig has had and extra parameter inserted at the beginning of its
parameter list. (which I assume is for communicating the HRESULT return
value back to the C++ as this is a COM method call.)
The following code changes Solves the problem:
Changing Line: 6785 switch (m->sig->params [param_num]->type) {
To: (m->sig->params [param_num + 1]->type) {
Changing Line: 6875 mono_mb_emit_ldarg (mb, param_num);
to mono_mb_emit_ldarg (mb, param_num + 1);
However I strongly suspect that this breaks all non COM marshaled method
calls the marshal Arrays.
So I could optionally do it by doing something like:
if (spec && (spec->native == MONO_NATIVE_IUNKNOWN ||
spec->native == MONO_NATIVE_IDISPATCH ||
spec->native == MONO_NATIVE_INTERFACE))
param_num++;
(param_num is initially set from spec->data.array_data.param_num)
And so would work for COM method calls and non COM method calls.
Could someone tell me if this is the correct place to adjust the
param_num or should
spec->data.array_data.param_num be expected to contain the adjusted
value?
Thanks
Tom
More information about the Mono-devel-list
mailing list