Add PInvoke/SizeParamIndex tests (#19348)
[platform/upstream/coreclr.git] / tests / src / Interop / PInvoke / SizeParamIndex / ReversePInvoke / PassingByOut / PassingByOutTest.cs
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.
4
5 using System;
6 using System.Runtime.InteropServices;
7 using TestLibrary;
8
9 public class ReversePInvoke_MashalArrayByOut_AsManagedTest
10 {
11     public static int arrSize = 10;
12
13     public static int failures = 0;
14
15     #region Func Sig
16
17     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
18     private static extern bool DoCallBack_MarshalByteArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelByteArrByOutAsCdeclCaller caller);
19     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
20     private static extern bool DoCallBack_MarshalSbyteArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelSbyteArrByOutAsCdeclCaller caller);
21     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
22     private static extern bool DoCallBack_MarshalShortArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelShortArrByOutAsCdeclCaller caller);
23     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
24     private static extern bool DoCallBack_MarshalShortArrayReturnNegativeSize_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelShortArrByOutAsCdeclCaller caller);
25     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
26     private static extern bool DoCallBack_MarshalUshortArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelUshortArrByOutAsCdeclCaller caller);
27     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
28     private static extern bool DoCallBack_MarshalInt32Array_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelInt32ArrByOutAsCdeclCaller caller);
29     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
30     private static extern bool DoCallBack_MarshalUint32Array_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelUint32ArrByOutAsCdeclCaller caller);
31     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
32     private static extern bool DoCallBack_MarshalLongArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelLongArrByOutAsCdeclCaller caller);
33     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
34     private static extern bool DoCallBack_MarshalUlongArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelUlongArrByOutAsCdeclCaller caller);
35     [DllImport("ReversePInvokePassingByOutNative", CallingConvention = CallingConvention.Cdecl)]
36     private static extern bool DoCallBack_MarshalStringArray_AsParam_AsByOut([MarshalAs(UnmanagedType.FunctionPtr)]DelStringArrByOutAsCdeclCaller caller);
37
38     #endregion
39
40     #region Delegate Method
41
42     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
43     public delegate bool DelByteArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out byte[] arrArg, out byte arraySize);
44     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
45     public delegate bool DelSbyteArrByOutAsCdeclCaller(out sbyte arraySize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] out sbyte[] arrArg);
46     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
47     public delegate bool DelShortArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out short[] arrArg, out short arraySize);
48     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
49     public delegate bool DelUshortArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out ushort[] arrArg, out ushort arraySize);
50     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
51     public delegate bool DelInt32ArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out Int32[] arrArg, out Int32 arraySize);
52     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
53     public delegate bool DelUint32ArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out UInt32[] arrArg, out UInt32 arraySize);
54     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
55     public delegate bool DelLongArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out long[] arrArg, out long arraySize);
56     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
57     public delegate bool DelUlongArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out ulong[] arrArg, out ulong arraySize);
58     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
59     public delegate bool DelStringArrByOutAsCdeclCaller([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.BStr)] out string[] arrArg, out Int32 arraySize);
60     
61     #endregion
62
63     #region Test Method
64
65     //Type: byte ==> BYTE    Array Size: byte.MinValue ==> 20
66     public static bool TestMethodForByteArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out byte[] arrArg, out byte arraySize)
67     {
68         arrArg = Helper.GetExpChangeArray<byte>(20);
69         arraySize = 20;
70         return true;
71     }
72
73     //Type: sbyte ==> CHAR  Array Size: 1 ==> sbyte.MaxValue
74     public static bool TestMethodForSbyteArray_AsReversePInvokeByOut_AsCdecl(out sbyte arraySize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] out sbyte[] arrArg)
75     {
76         arrArg = Helper.GetExpChangeArray<sbyte>(sbyte.MaxValue);
77         arraySize = sbyte.MaxValue;
78         return true;
79     }
80
81     //Type: short ==> SHORT  Array Size: -1 ==> 20(Actual 10 ==> 20)
82     public static bool TestMethodForShortArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out short[] arrArg, out short arraySize)
83     {
84         arrArg = Helper.GetExpChangeArray<short>(20);
85         arraySize = 20;
86         return true;
87     }
88
89     //Type: short ==> SHORT  Array Size: 10 ==> -1(Actual 10 ==> 20)
90     public static bool TestMethodForShortArrayReturnNegativeSize_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out short[] arrArg, out short arraySize)
91     {
92         arrArg = Helper.GetExpChangeArray<short>(20);
93         arraySize = -1;
94         return true;
95     }
96
97     //Type: ushort ==> USHORT  Array Size: ushort.MaxValue ==> 20
98     public static bool TestMethodForUshortArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out ushort[] arrArg, out ushort arraySize)
99     {
100         arrArg = Helper.GetExpChangeArray<ushort>(20);
101         arraySize = 20;
102         return true;
103     }
104
105     //Type: Int32 ==> LONG    Array Size: 10 ==> 20
106     public static bool TestMethodForInt32Array_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out Int32[] arrArg, out Int32 arraySize)
107     {
108         arrArg = Helper.GetExpChangeArray<Int32>(20);
109         arraySize = 20;
110         return true;
111     }
112
113     //Type: UInt32 ==> ULONG    Array Size: 10 ==> 20
114     public static bool TestMethodForUint32Array_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out UInt32[] arrArg, out UInt32 arraySize)
115     {
116         arrArg = Helper.GetExpChangeArray<UInt32>(20);
117         arraySize = 20;
118         return true;
119     }
120
121     //Type: long ==> LONGLONG    Array Size: 10 ==> 20
122     public static bool TestMethodForLongArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out long[] arrArg, out long arraySize)
123     {
124         arrArg = Helper.GetExpChangeArray<long>(20);
125         arraySize = 20;
126         return true;
127     }
128
129     //Type: ulong ==> ULONGLONG    Array Size: 10 ==> 20
130     public static bool TestMethodForUlongArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out ulong[] arrArg, out ulong arraySize)
131     {
132         arrArg = Helper.GetExpChangeArray<ulong>(20);
133         arraySize = 20;
134         return true;
135     }
136
137     //Type: string ==> BSTR    Array Size: 10 ==> 20
138     public static bool TestMethodForStringArray_AsReversePInvokeByOut_AsCdecl([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.BStr)] out string[] arrArg, out Int32 arraySize)
139     {
140         arrArg = Helper.GetExpChangeArray<string>(20);
141         arraySize = 20;
142         return true;
143     }
144
145     #endregion
146
147     public static void RunTestByOut()
148     {
149         Console.WriteLine("ReversePInvoke C-Style Array marshaled by out with SizeParamIndex attribute(by out Array size).");
150
151         //Common value type
152         Console.WriteLine("\tScenario 1 : byte ==> BYTE, Array_Size = byte.MinValue, Return_Array_Size = 20");
153         Assert.IsTrue(DoCallBack_MarshalByteArray_AsParam_AsByOut(new DelByteArrByOutAsCdeclCaller(TestMethodForByteArray_AsReversePInvokeByOut_AsCdecl)));
154         Console.WriteLine("\t\tMarshalByteArray_AsReversePInvokeByOut_AsCdecl Passed!");
155
156         Console.WriteLine("\tScenario 2 : sbyte ==> CHAR, Array_Size = 1, Return_Array_Size = sbyte.Max");
157         Assert.IsTrue(DoCallBack_MarshalSbyteArray_AsParam_AsByOut(new DelSbyteArrByOutAsCdeclCaller(TestMethodForSbyteArray_AsReversePInvokeByOut_AsCdecl)));
158         Console.WriteLine("\t\tMarshalSbyteArray_AsReversePInvokeByOut_AsCdecl Passed!");
159
160         Console.WriteLine("\tScenario 3 : short ==> SHORT, Array_Size = -1, Return_Array_Size = 20");
161         Assert.IsTrue(DoCallBack_MarshalShortArray_AsParam_AsByOut(new DelShortArrByOutAsCdeclCaller(TestMethodForShortArray_AsReversePInvokeByOut_AsCdecl)));
162         Console.WriteLine("\t\tMarshalShortArray_AsReversePInvokeByOut_AsCdecl Failed!");
163
164         Console.WriteLine("\tScenario 4 : short ==> SHORT, Array_Size = 10, Return_Array_Size = -1");
165         Assert.IsTrue(DoCallBack_MarshalShortArrayReturnNegativeSize_AsParam_AsByOut(new DelShortArrByOutAsCdeclCaller(TestMethodForShortArrayReturnNegativeSize_AsReversePInvokeByOut_AsCdecl)));
166         Console.WriteLine("\t\tMarshalShortArray_AsReversePInvokeByOut_AsCdecl Passed!");
167
168         Console.WriteLine("\tScenario 5 : ushort ==> USHORT, Array_Size = ushort.MaxValue, Return_Array_Size = 20");
169         Assert.IsTrue(DoCallBack_MarshalUshortArray_AsParam_AsByOut(new DelUshortArrByOutAsCdeclCaller(TestMethodForUshortArray_AsReversePInvokeByOut_AsCdecl)));
170         Console.WriteLine("\t\tMarshalUshortArray_AsReversePInvokeByOut_AsCdecl Passed!");
171
172         Console.WriteLine("\tScenario 6 : Int32 ==> LONG, Array_Size = 10, Return_Array_Size = 20");
173         Assert.IsTrue(DoCallBack_MarshalInt32Array_AsParam_AsByOut(new DelInt32ArrByOutAsCdeclCaller(TestMethodForInt32Array_AsReversePInvokeByOut_AsCdecl)));
174         Console.WriteLine("\t\tMarshalInt32Array_AsReversePInvokeByOut_AsCdecl Passed!");
175
176         Console.WriteLine("\tScenario 7 : UInt32 ==> ULONG, Array_Size = 10, Return_Array_Size = 20");
177         Assert.IsTrue(DoCallBack_MarshalUint32Array_AsParam_AsByOut(new DelUint32ArrByOutAsCdeclCaller(TestMethodForUint32Array_AsReversePInvokeByOut_AsCdecl)));
178         Console.WriteLine("\t\tMarshalUint32Array_AsReversePInvokeByOut_AsCdecl Passed!");
179
180         Console.WriteLine("\tScenario 8 : long ==> LONGLONG, Array_Size = 10, Return_Array_Size = 20");
181         Assert.IsTrue(DoCallBack_MarshalLongArray_AsParam_AsByOut(new DelLongArrByOutAsCdeclCaller(TestMethodForLongArray_AsReversePInvokeByOut_AsCdecl)));
182         Console.WriteLine("\t\tMarshalLongArray_AsReversePInvokeByOut_AsCdecl Passed!");
183
184         Console.WriteLine("\tScenario 9 : ulong ==> ULONGLONG, Array_Size = 10, Return_Array_Size = 20");
185         Assert.IsTrue(DoCallBack_MarshalUlongArray_AsParam_AsByOut(new DelUlongArrByOutAsCdeclCaller(TestMethodForUlongArray_AsReversePInvokeByOut_AsCdecl)));
186         Console.WriteLine("\t\tMarshalUlongArray_AsReversePInvokeByOut_AsCdecl Passed!");
187
188         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
189         {
190             Console.WriteLine("\tScenario 10 : string ==> BSTR, Array_Size = 10, Return_Array_Size = 20");
191             Assert.IsTrue(DoCallBack_MarshalStringArray_AsParam_AsByOut(new DelStringArrByOutAsCdeclCaller(TestMethodForStringArray_AsReversePInvokeByOut_AsCdecl)));
192             Console.WriteLine("\t\tMarshalStringArray_AsReversePInvokeByOut_AsCdecl Passed!");
193         }
194     }
195
196     public static int Main()
197     {
198         try{
199             RunTestByOut();
200             return 100;
201         }
202         catch (Exception e)
203         {
204             Console.WriteLine($"Test Failure: {e}");
205             return 101;
206         }
207     }
208 }