New test.
[mono.git] / mono / tests / cominterop.cs
1 //
2 // cominterop.cs:
3 //
4 //  Tests for COM Interop related features
5 //
6
7 using System;
8 using System.Runtime.CompilerServices;
9 using System.Runtime.InteropServices;
10
11 public class Tests
12 {
13
14         [DllImport("libtest")]
15         public static extern int mono_test_marshal_bstr_in([MarshalAs(UnmanagedType.BStr)]string str);
16
17         [DllImport("libtest")]
18     public static extern int mono_test_marshal_bstr_out([MarshalAs(UnmanagedType.BStr)] out string str);
19
20     [DllImport("libtest")]
21     public static extern int mono_test_marshal_bstr_in_null([MarshalAs(UnmanagedType.BStr)]string str);
22
23     [DllImport("libtest")]
24     public static extern int mono_test_marshal_bstr_out_null([MarshalAs(UnmanagedType.BStr)] out string str);
25
26         [DllImport("libtest")]
27         public static extern int mono_test_marshal_variant_in_sbyte([MarshalAs(UnmanagedType.Struct)]object obj);
28
29         [DllImport("libtest")]
30         public static extern int mono_test_marshal_variant_in_byte([MarshalAs(UnmanagedType.Struct)]object obj);
31
32         [DllImport("libtest")]
33         public static extern int mono_test_marshal_variant_in_short([MarshalAs(UnmanagedType.Struct)]object obj);
34
35         [DllImport("libtest")]
36         public static extern int mono_test_marshal_variant_in_ushort([MarshalAs(UnmanagedType.Struct)]object obj);
37
38         [DllImport("libtest")]
39         public static extern int mono_test_marshal_variant_in_int([MarshalAs(UnmanagedType.Struct)]object obj);
40
41         [DllImport("libtest")]
42         public static extern int mono_test_marshal_variant_in_uint([MarshalAs(UnmanagedType.Struct)]object obj);
43
44         [DllImport("libtest")]
45         public static extern int mono_test_marshal_variant_in_long([MarshalAs(UnmanagedType.Struct)]object obj);
46
47         [DllImport("libtest")]
48         public static extern int mono_test_marshal_variant_in_ulong([MarshalAs(UnmanagedType.Struct)]object obj);
49
50         [DllImport("libtest")]
51         public static extern int mono_test_marshal_variant_in_float([MarshalAs(UnmanagedType.Struct)]object obj);
52
53         [DllImport("libtest")]
54         public static extern int mono_test_marshal_variant_in_double([MarshalAs(UnmanagedType.Struct)]object obj);
55
56         [DllImport("libtest")]
57         public static extern int mono_test_marshal_variant_in_bstr([MarshalAs(UnmanagedType.Struct)]object obj);
58
59         [DllImport("libtest")]
60         public static extern int mono_test_marshal_variant_out_sbyte([MarshalAs(UnmanagedType.Struct)]out object obj);
61
62         [DllImport("libtest")]
63         public static extern int mono_test_marshal_variant_out_byte([MarshalAs(UnmanagedType.Struct)]out object obj);
64
65         [DllImport("libtest")]
66         public static extern int mono_test_marshal_variant_out_short([MarshalAs(UnmanagedType.Struct)]out object obj);
67
68         [DllImport("libtest")]
69         public static extern int mono_test_marshal_variant_out_ushort([MarshalAs(UnmanagedType.Struct)]out object obj);
70
71         [DllImport("libtest")]
72         public static extern int mono_test_marshal_variant_out_int([MarshalAs(UnmanagedType.Struct)]out object obj);
73
74         [DllImport("libtest")]
75         public static extern int mono_test_marshal_variant_out_uint([MarshalAs(UnmanagedType.Struct)]out object obj);
76
77         [DllImport("libtest")]
78         public static extern int mono_test_marshal_variant_out_long([MarshalAs(UnmanagedType.Struct)]out object obj);
79
80         [DllImport("libtest")]
81         public static extern int mono_test_marshal_variant_out_ulong([MarshalAs(UnmanagedType.Struct)]out object obj);
82
83         [DllImport("libtest")]
84         public static extern int mono_test_marshal_variant_out_float([MarshalAs(UnmanagedType.Struct)]out object obj);
85
86         [DllImport("libtest")]
87         public static extern int mono_test_marshal_variant_out_double([MarshalAs(UnmanagedType.Struct)]out object obj);
88
89         [DllImport("libtest")]
90         public static extern int mono_test_marshal_variant_out_bstr([MarshalAs(UnmanagedType.Struct)]out object obj);
91
92     [DllImport ("libtest")]
93     public static extern int mono_test_marshal_com_object_create (out IntPtr pUnk);
94
95     [DllImport ("libtest")]
96     public static extern int mono_test_marshal_com_object_destroy (IntPtr pUnk);
97
98     [DllImport ("libtest")]
99     public static extern int mono_test_marshal_com_object_ref_count (IntPtr pUnk);
100
101         public static int Main() {
102
103         bool isWindows = !(((int)Environment.OSVersion.Platform == 4) || 
104             ((int)Environment.OSVersion.Platform == 128));
105                 if (isWindows) {
106                         #region BSTR Tests
107
108                         string str;
109                         if (mono_test_marshal_bstr_in ("mono_test_marshal_bstr_in") != 0)
110                                 return 1;
111                         if (mono_test_marshal_bstr_out (out str) != 0 || str != "mono_test_marshal_bstr_out")
112                 return 2;
113             if (mono_test_marshal_bstr_in_null (null) != 0)
114                 return 1;
115             if (mono_test_marshal_bstr_out_null (out str) != 0 || str != null)
116                 return 2;
117
118                         #endregion // BSTR Tests
119
120                         #region VARIANT Tests
121
122                         object obj;
123                         if (mono_test_marshal_variant_in_sbyte ((sbyte)100) != 0)
124                                 return 13;
125                         if (mono_test_marshal_variant_in_byte ((byte)100) != 0)
126                                 return 14;
127                         if (mono_test_marshal_variant_in_short ((short)314) != 0)
128                                 return 15;
129                         if (mono_test_marshal_variant_in_ushort ((ushort)314) != 0)
130                                 return 16;
131                         if (mono_test_marshal_variant_in_int ((int)314) != 0)
132                                 return 17;
133                         if (mono_test_marshal_variant_in_uint ((uint)314) != 0)
134                                 return 18;
135                         if (mono_test_marshal_variant_in_long ((long)314) != 0)
136                                 return 19;
137                         if (mono_test_marshal_variant_in_ulong ((ulong)314) != 0)
138                                 return 20;
139                         if (mono_test_marshal_variant_in_float ((float)3.14) != 0)
140                                 return 21;
141                         if (mono_test_marshal_variant_in_double ((double)3.14) != 0)
142                                 return 22;
143                         if (mono_test_marshal_variant_in_bstr ("PI") != 0)
144                                 return 23;
145                         if (mono_test_marshal_variant_out_sbyte (out obj) != 0 || (sbyte)obj != 100)
146                                 return 24;
147                         if (mono_test_marshal_variant_out_byte (out obj) != 0 || (byte)obj != 100)
148                                 return 25;
149                         if (mono_test_marshal_variant_out_short (out obj) != 0 || (short)obj != 314)
150                                 return 26;
151                         if (mono_test_marshal_variant_out_ushort (out obj) != 0 || (ushort)obj != 314)
152                                 return 27;
153                         if (mono_test_marshal_variant_out_int (out obj) != 0 || (int)obj != 314)
154                                 return 28;
155                         if (mono_test_marshal_variant_out_uint (out obj) != 0 || (uint)obj != 314)
156                                 return 29;
157                         if (mono_test_marshal_variant_out_long (out obj) != 0 || (long)obj != 314)
158                                 return 30;
159                         if (mono_test_marshal_variant_out_ulong (out obj) != 0 || (ulong)obj != 314)
160                                 return 31;
161                         if (mono_test_marshal_variant_out_float (out obj) != 0 || ((float)obj - 3.14) / 3.14 > .001)
162                                 return 32;
163                         if (mono_test_marshal_variant_out_double (out obj) != 0 || ((double)obj - 3.14) / 3.14 > .001)
164                                 return 33;
165                         if (mono_test_marshal_variant_out_bstr (out obj) != 0 || (string)obj != "PI")
166                                 return 34;
167
168                         #endregion // VARIANT Tests
169
170                         #region Marshal COM Interop Tests
171
172                         IntPtr pUnk;
173                         if (mono_test_marshal_com_object_create (out pUnk) != 0)
174                                 return 65;
175
176                         if (mono_test_marshal_com_object_ref_count (pUnk) != 1)
177                                 return 46;
178
179                         if (Marshal.AddRef (pUnk) != 2)
180                                 return 47;
181
182                         if (mono_test_marshal_com_object_ref_count (pUnk) != 2)
183                                 return 48;
184
185                         if (Marshal.Release (pUnk) != 1)
186                                 return 49;
187
188                         if (mono_test_marshal_com_object_ref_count (pUnk) != 1)
189                                 return 50;
190
191                         object com_obj = Marshal.GetObjectForIUnknown (pUnk);
192
193                         if (com_obj == null)
194                                 return 51;
195
196                         IMath imath = com_obj as IMath;
197
198                         if (imath == null)
199                                 return 52;
200
201                         if (imath.Add (20, 10) != 30)
202                                 return 53;
203
204                         if (imath.Subtract (20, 10) != 10)
205                                 return 54;
206
207                         IMath same1, same2;
208                         imath.Same (out same1);
209                         imath.Same (out same2);
210                         if (same1 != same2)
211                                 return 55;
212
213                         if (!same1.Equals (same2))
214                                 return 56;
215
216                         IMath diff1, diff2;
217                         imath.Different (out diff1);
218                         imath.Different (out diff2);
219                         if (diff1 == diff2)
220                                 return 57;
221
222                         if (diff1.Equals (diff2))
223                                 return 58;
224
225                         // same1 & same2 share a RCW
226                         if (Marshal.ReleaseComObject (same1) != 1)
227                                 return 59;
228
229                         if (Marshal.ReleaseComObject (same2) != 0)
230                                 return 60;
231
232
233                         if (Marshal.ReleaseComObject (diff1) != 0 ||
234                                 Marshal.ReleaseComObject (diff2) != 0)
235                                 return 61;
236
237                         IntPtr pUnk2 = Marshal.GetIUnknownForObject (imath);
238                         if (pUnk2 == IntPtr.Zero)
239                                 return 70;
240
241                         if (pUnk != pUnk2)
242                                 return 71;
243
244                         IntPtr pDisp = Marshal.GetIDispatchForObject (imath);
245                         if (pDisp == IntPtr.Zero)
246                                 return 72;
247
248                         if (pUnk != pDisp)
249                                 return 73;
250
251
252                         //if (mono_test_marshal_com_object_destroy (pUnk) != 0)
253                         //    return 71;
254                         #endregion // Marshal COM Interop Tests
255                 }
256
257         return 0;
258         }
259
260     [ComImport()]
261     [Guid ("00000000-0000-0000-0000-000000000001")]
262     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
263     public interface IMath
264     {
265         [MethodImplAttribute (MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime)]
266         int Add (int a, int b);
267         [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
268                 int Subtract (int a, int b);
269                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
270                 int Same ([MarshalAs(UnmanagedType.Interface)] out IMath imath);
271                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
272                 int Different ([MarshalAs (UnmanagedType.Interface)] out IMath imath);
273     }
274
275         [ComImport ()]
276         [Guid ("00000000-0000-0000-0000-000000000002")]
277         public class Foo : IMath
278         {
279                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
280                 public extern int Add (int a, int b);
281                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
282                 public extern int Subtract (int a, int b);
283                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
284                 public extern int Same ([MarshalAs (UnmanagedType.Interface)] out IMath imath);
285                 [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
286                 public extern int Different ([MarshalAs (UnmanagedType.Interface)] out IMath imath);
287         }
288 }