1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 using System.Runtime.InteropServices;
9 public class ReversePInvoke_MashalArrayByRef_AsManagedTest
11 public static int arrSize = 10;
13 public static int failures = 0;
17 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
18 private static extern bool DoCallBack_MarshalByteArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelByteArrByRefAsCdeclCaller caller);
19 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
20 private static extern bool DoCallBack_MarshalSbyteArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelSbyteArrByRefAsCdeclCaller caller);
21 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
22 private static extern bool DoCallBack_MarshalShortArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelShortArrByRefAsCdeclCaller caller);
23 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
24 private static extern bool DoCallBack_MarshalShortArrayReturnNegativeSize_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelShortArrByRefAsCdeclCaller caller);
25 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
26 private static extern bool DoCallBack_MarshalUshortArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelUshortArrByRefAsCdeclCaller caller);
27 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
28 private static extern bool DoCallBack_MarshalInt32Array_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelInt32ArrByRefAsCdeclCaller caller);
29 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
30 private static extern bool DoCallBack_MarshalUint32Array_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelUint32ArrByRefAsCdeclCaller caller);
31 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
32 private static extern bool DoCallBack_MarshalLongArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelLongArrByRefAsCdeclCaller caller);
33 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
34 private static extern bool DoCallBack_MarshalUlongArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelUlongArrByRefAsCdeclCaller caller);
35 [DllImport("ReversePInvokePassingByRefNative", CallingConvention = CallingConvention.Cdecl)]
36 private static extern bool DoCallBack_MarshalStringArray_AsParam_AsByRef([MarshalAs(UnmanagedType.FunctionPtr)]DelStringArrByRefAsCdeclCaller caller);
40 #region Delegate Method
42 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
43 public delegate bool DelByteArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref byte[] arrArg, ref byte arraySize);
44 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
45 public delegate bool DelSbyteArrByRefAsCdeclCaller(ref sbyte arraySize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ref sbyte[] arrArg);
46 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
47 public delegate bool DelShortArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref short[] arrArg, ref short arraySize);
48 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
49 public delegate bool DelUshortArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref ushort[] arrArg, ref ushort arraySize);
50 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
51 public delegate bool DelInt32ArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref Int32[] arrArg, ref Int32 arraySize);
52 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
53 public delegate bool DelUint32ArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref UInt32[] arrArg, ref UInt32 arraySize);
54 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
55 public delegate bool DelLongArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref long[] arrArg, ref long arraySize);
56 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
57 public delegate bool DelUlongArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref ulong[] arrArg, ref ulong arraySize);
58 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
59 public delegate bool DelStringArrByRefAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.BStr)] ref string[] arrArg, ref Int32 arraySize);
65 //Type: byte ==> BYTE Array Size: byte.MinValue ==> 20
66 public static bool TestMethodForByteArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref byte[] arrArg, ref byte arraySize)
68 if (arraySize == byte.MinValue)
69 return Helper.CheckAndChangeArray<byte>(ref arrArg, ref arraySize, (Int32)byte.MinValue, 20);
73 //Type: sbyte ==> CHAR Array Size: 1 ==> sbyte.MaxValue
74 public static bool TestMethodForSbyteArray_AsReversePInvokeByRef_AsCdecl(ref sbyte arraySize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ref sbyte[] arrArg)
77 return Helper.CheckAndChangeArray<sbyte>(ref arrArg, ref arraySize, 1, (Int32)sbyte.MaxValue);
81 //Type: short ==> SHORT Array Size: -1 ==> 20(Actual 10 ==> 20)
82 public static bool TestMethodForShortArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref short[] arrArg, ref short arraySize)
85 return Helper.CheckAndChangeArray<short>(ref arrArg, ref arraySize, 10, 20);
89 //Type: short ==> SHORT Array Size: 10 ==> -1(Actual 10 ==> 20)
90 public static bool TestMethodForShortArrayReturnNegativeSize_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref short[] arrArg, ref short arraySize)
94 Helper.CheckAndChangeArray<short>(ref arrArg, ref arraySize, 10, 20);
101 //Type: ushort ==> USHORT Array Size: ushort.MaxValue ==> 20
102 public static bool TestMethodForUshortArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref ushort[] arrArg, ref ushort arraySize)
104 if (arraySize == ushort.MaxValue)
105 return Helper.CheckAndChangeArray<ushort>(ref arrArg, ref arraySize, (Int32)ushort.MaxValue, 20);
109 //Type: Int32 ==> LONG Array Size: 10 ==> 20
110 public static bool TestMethodForInt32Array_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref Int32[] arrArg, ref Int32 arraySize)
113 return Helper.CheckAndChangeArray<Int32>(ref arrArg, ref arraySize, 10, 20);
117 //Type: UInt32 ==> ULONG Array Size: 10 ==> 20
118 public static bool TestMethodForUint32Array_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref UInt32[] arrArg, ref UInt32 arraySize)
121 return Helper.CheckAndChangeArray<UInt32>(ref arrArg, ref arraySize, 10, 20);
125 //Type: long ==> LONGLONG Array Size: 10 ==> 20
126 public static bool TestMethodForLongArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref long[] arrArg, ref long arraySize)
129 return Helper.CheckAndChangeArray<long>(ref arrArg, ref arraySize, 10, 20);
133 //Type: ulong ==> ULONGLONG Array Size: 10 ==> 20
134 public static bool TestMethodForUlongArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref ulong[] arrArg, ref ulong arraySize)
137 return Helper.CheckAndChangeArray<ulong>(ref arrArg, ref arraySize, 10, 20);
141 //Type: string ==> BSTR Array Size: 10 ==> 20
142 public static bool TestMethodForStringArray_AsReversePInvokeByRef_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.BStr)] ref string[] arrArg, ref Int32 arraySize)
144 string[] actualArr = Helper.InitArray<string>(10);
145 if (!Helper.EqualArray<string>(arrArg, arraySize, actualArr, 10))
151 arrArg = Helper.GetExpChangeArray<string>(20);
157 public static void RunTestByRef()
159 Console.WriteLine("ReversePInvoke C-Style Array marshaled by ref with SizeParamIndex attribute(by ref Array size).");
162 Console.WriteLine("\tScenario 1 : byte ==> BYTE, Array_Size = byte.MinValue, Return_Array_Size = 20");
163 Assert.IsTrue(DoCallBack_MarshalByteArray_AsParam_AsByRef(new DelByteArrByRefAsCdeclCaller(TestMethodForByteArray_AsReversePInvokeByRef_AsCdecl)));
164 Console.WriteLine("\t\tMarshalByteArray_AsReversePInvokeByRef_AsCdecl Passed!");
166 Console.WriteLine("\tScenario 2 : sbyte ==> CHAR, Array_Size = 1, Return_Array_Size = sbyte.Max");
167 Assert.IsTrue(DoCallBack_MarshalSbyteArray_AsParam_AsByRef(new DelSbyteArrByRefAsCdeclCaller(TestMethodForSbyteArray_AsReversePInvokeByRef_AsCdecl)));
168 Console.WriteLine("\t\tMarshalSbyteArray_AsReversePInvokeByRef_AsCdecl Passed!");
170 // We don't support exception interop in .NET Core off-Windows.
171 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
173 Console.WriteLine("\tScenario 3 : short ==> SHORT, Array_Size = -1, Return_Array_Size = 20");
174 Assert.Throws<OverflowException>(() => DoCallBack_MarshalShortArray_AsParam_AsByRef(new DelShortArrByRefAsCdeclCaller(TestMethodForShortArray_AsReversePInvokeByRef_AsCdecl)));
175 Console.WriteLine("\t\tMarshalShortArray_AsReversePInvokeByRef_AsCdecl Passed!");
179 Console.WriteLine("\tScenario 4 : short ==> SHORT, Array_Size = 10, Return_Array_Size = -1");
180 Assert.IsTrue(DoCallBack_MarshalShortArrayReturnNegativeSize_AsParam_AsByRef(new DelShortArrByRefAsCdeclCaller(TestMethodForShortArrayReturnNegativeSize_AsReversePInvokeByRef_AsCdecl)));
181 Console.WriteLine("\t\tMarshalShortArray_AsReversePInvokeByRef_AsCdecl Passed!");
183 Console.WriteLine("\tScenario 5 : ushort ==> USHORT, Array_Size = ushort.MaxValue, Return_Array_Size = 20");
184 Assert.IsTrue(DoCallBack_MarshalUshortArray_AsParam_AsByRef(new DelUshortArrByRefAsCdeclCaller(TestMethodForUshortArray_AsReversePInvokeByRef_AsCdecl)));
185 Console.WriteLine("\t\tMarshalUshortArray_AsReversePInvokeByRef_AsCdecl Passed!");
187 Console.WriteLine("\tScenario 6 : Int32 ==> LONG, Array_Size = 10, Return_Array_Size = 20");
188 Assert.IsTrue(DoCallBack_MarshalInt32Array_AsParam_AsByRef(new DelInt32ArrByRefAsCdeclCaller(TestMethodForInt32Array_AsReversePInvokeByRef_AsCdecl)));
189 Console.WriteLine("\t\tMarshalInt32Array_AsReversePInvokeByRef_AsCdecl Passed!");
191 Console.WriteLine("\tScenario 7 : UInt32 ==> ULONG, Array_Size = 10, Return_Array_Size = 20");
192 Assert.IsTrue(DoCallBack_MarshalUint32Array_AsParam_AsByRef(new DelUint32ArrByRefAsCdeclCaller(TestMethodForUint32Array_AsReversePInvokeByRef_AsCdecl)));
193 Console.WriteLine("\t\tMarshalUint32Array_AsReversePInvokeByRef_AsCdecl Passed!");
195 Console.WriteLine("\tScenario 8 : long ==> LONGLONG, Array_Size = 10, Return_Array_Size = 20");
196 Assert.IsTrue(DoCallBack_MarshalLongArray_AsParam_AsByRef(new DelLongArrByRefAsCdeclCaller(TestMethodForLongArray_AsReversePInvokeByRef_AsCdecl)));
197 Console.WriteLine("\t\tMarshalLongArray_AsReversePInvokeByRef_AsCdecl Passed!");
199 Console.WriteLine("\tScenario 9 : ulong ==> ULONGLONG, Array_Size = 10, Return_Array_Size = 20");
200 Assert.IsTrue(DoCallBack_MarshalUlongArray_AsParam_AsByRef(new DelUlongArrByRefAsCdeclCaller(TestMethodForUlongArray_AsReversePInvokeByRef_AsCdecl)));
201 Console.WriteLine("\t\tMarshalUlongArray_AsReversePInvokeByRef_AsCdecl Passed!");
203 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
205 Console.WriteLine("\tScenario 10 : string ==> BSTR, Array_Size = 10, Return_Array_Size = 20");
206 Assert.IsTrue(DoCallBack_MarshalStringArray_AsParam_AsByRef(new DelStringArrByRefAsCdeclCaller(TestMethodForStringArray_AsReversePInvokeByRef_AsCdecl)));
207 Console.WriteLine("\t\tMarshalStringArray_AsReversePInvokeByRef_AsCdecl Passed!");
211 public static int Main()
219 Console.WriteLine($"Test Failure: {e}");