-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Description
The following source will generated an unmanaged to managed stub that doesn't work as expected.
// Definition
[GeneratedComInterface]
[Guid("8A2AF35B-D028-4191-A01F-3422AB0CF724")]
public partial interface IInterface1
{
void M(
int bufferSize,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? buffer1,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? buffer2);
}// Usage from native
IInterface*1 i = ...
int buffer1[10];
i->M(10, buffer1, nullptr); // Note the second buffer is null, but using the same buffer length.The generated marshalling logic for unmanaged to managed has a logical flaw in it. See comment below.
[global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(CallConvs = new[] { typeof(global::System.Runtime.CompilerServices.CallConvMemberFunction) })]
internal static int ABI_M(global::System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch* __this_native, int bufferSize, int* __buffer1_native, int* __buffer2_native)
{
global::Program.IInterface1 @this = default;
int[] buffer1 = default;
int[] buffer2 = default;
int __retVal = default;
// Setup - Perform required setup.
int __buffer2_native__numElements;
global::System.Runtime.CompilerServices.Unsafe.SkipInit(out __buffer2_native__numElements);
int __buffer1_native__numElements;
global::System.Runtime.CompilerServices.Unsafe.SkipInit(out __buffer1_native__numElements);
try
{
// Unmarshal - Convert native data to managed data.
global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetManagedValuesDestination(buffer2).Clear();
// The below should likely be: "__buffer2_native == null ? 0 : bufferSize"
__buffer2_native__numElements = bufferSize;
buffer2 = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.AllocateContainerForManagedElements(__buffer2_native, __buffer2_native__numElements);
global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetManagedValuesDestination(buffer1).Clear();
// The below should likely be: "__buffer1_native == null ? 0 : bufferSize"
__buffer1_native__numElements = bufferSize;
buffer1 = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.AllocateContainerForManagedElements(__buffer1_native, __buffer1_native__numElements);
@this = global::System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch.GetInstance<global::Program.IInterface1>(__this_native);
@this.M(bufferSize, buffer1, buffer2);
// NotifyForSuccessfulInvoke - Keep alive any managed objects that need to stay alive across the call.
__retVal = 0; // S_OK
// Marshal - Convert managed data to native data.
global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetManagedValuesDestination(buffer2).CopyTo(global::System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetUnmanagedValuesSource(__buffer2_native, __buffer2_native__numElements)), global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetUnmanagedValuesSource(__buffer2_native, __buffer2_native__numElements).Length));
global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetManagedValuesDestination(buffer1).CopyTo(global::System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetUnmanagedValuesSource(__buffer1_native, __buffer1_native__numElements)), global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<int, int>.GetUnmanagedValuesSource(__buffer1_native, __buffer1_native__numElements).Length));
}
catch (global::System.Exception __exception)
{
__retVal = global::System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller<int>.ConvertToUnmanaged(__exception);
}
return __retVal;
}Copilot
Metadata
Metadata
Assignees
Type
Projects
Status
No status