2 // System.Runtime.InteropServices.Marshal Test Cases
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
10 using NUnit.Framework;
13 using System.Reflection;
15 using System.Reflection.Emit;
17 using System.Runtime.InteropServices;
18 using System.Security;
21 namespace MonoTests.System.Runtime.InteropServices
24 public class MarshalTest
26 [StructLayout (LayoutKind.Sequential)]
31 public class ClsNoLayout {
35 [StructLayout (LayoutKind.Explicit)]
37 [FieldOffset (0)] public int field;
40 [StructLayout (LayoutKind.Sequential)]
41 struct StrSequential {
49 [StructLayout (LayoutKind.Explicit)]
51 [FieldOffset (0)] public int field;
55 public void SizeOf_Class_LayoutSequential ()
57 Marshal.SizeOf (typeof (ClsSequential));
61 public void SizeOf_Class_LayoutNotSet ()
64 Marshal.SizeOf (typeof (ClsNoLayout));
66 } catch (ArgumentException ex) {
67 // Type '...MarshalTest+ClsNoLayout' cannot be
68 // marshaled as an unmanaged structure; no
69 // meaningful size or offset can be computed
70 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
71 Assert.IsNull (ex.InnerException, "#3");
72 Assert.IsNotNull (ex.Message, "#4");
77 public void SizeOf_Class_LayoutExplicit ()
79 Marshal.SizeOf (typeof (ClsExplicit));
83 public void SizeOf_Struct_LayoutSequential ()
85 Marshal.SizeOf (typeof (StrSequential));
89 public void SizeOf_Struct_LayoutNotSet ()
91 Marshal.SizeOf (typeof (StrNoLayout));
95 public void SizeOf_Struct_LayoutExplicit ()
97 Marshal.SizeOf (typeof (StrExplicit));
101 public void SizeOf_Array ()
104 Marshal.SizeOf (typeof (string []));
106 } catch (ArgumentException ex) {
107 // Type 'System.String[]' cannot be marshaled
108 // as an unmanaged structure; no meaningful
109 // size or offset can be computed
110 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
111 Assert.IsNull (ex.InnerException, "#3");
112 Assert.IsNotNull (ex.Message, "#4");
117 public unsafe void Sizeof_Pointer ()
119 int size = Marshal.SizeOf (typeof (char*));
120 Assert.IsTrue (size == 4 || size == 8);
124 public void PtrToStringWithNull ()
126 Assert.IsNull (Marshal.PtrToStringAnsi (IntPtr.Zero), "A");
127 Assert.IsNull (Marshal.PtrToStringUni (IntPtr.Zero), "C");
131 public void PtrToStringAnsi_Ptr_Zero ()
134 Marshal.PtrToStringAnsi (IntPtr.Zero, 0);
136 } catch (ArgumentNullException ex) {
137 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
138 Assert.IsNull (ex.InnerException, "#3");
139 Assert.IsNotNull (ex.Message, "#4");
140 Assert.AreEqual ("ptr", ex.ParamName, "#5");
145 public void PtrToStringWithUni_Ptr_Zero ()
148 Marshal.PtrToStringUni (IntPtr.Zero, 0);
150 } catch (ArgumentNullException ex) {
151 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
152 Assert.IsNull (ex.InnerException, "#3");
153 Assert.IsNotNull (ex.Message, "#4");
154 Assert.AreEqual ("ptr", ex.ParamName, "#5");
159 public unsafe void UnsafeAddrOfPinnedArrayElement ()
161 short[] sarr = new short [5];
164 IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement (sarr, 2);
165 Assert.AreEqual (3, *(short*) ptr.ToPointer ());
169 public void AllocHGlobalZeroSize ()
171 IntPtr ptr = Marshal.AllocHGlobal (0);
172 Assert.IsTrue (ptr != IntPtr.Zero);
173 Marshal.FreeHGlobal (ptr);
177 public void AllocCoTaskMemZeroSize ()
179 IntPtr ptr = Marshal.AllocCoTaskMem (0);
180 Assert.IsTrue (ptr != IntPtr.Zero);
181 Marshal.FreeCoTaskMem (ptr);
188 public static char d;
193 public void OffsetOf_FieldName_Static ()
196 Marshal.OffsetOf (typeof (Foo), "b");
198 } catch (ArgumentException ex) {
199 // Field passed in is not a marshaled member of
200 // the type '...MarshalTest+Foo'
201 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
202 Assert.IsNull (ex.InnerException, "#3");
203 Assert.IsNotNull (ex.Message, "#4");
204 Assert.AreEqual ("fieldName", ex.ParamName, "#5");
209 public void GetHINSTANCE ()
212 Assert.Ignore ("GetHINSTANCE only applies to .NET on Windows.");
216 StringBuilder fileName;
218 fileName = new StringBuilder (255);
219 a = Assembly.GetExecutingAssembly ();
220 hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
221 Assert.IsTrue (GetModuleFileName (hinstance, fileName,
222 fileName.Capacity) > 0, "#A1");
223 Assert.AreEqual (a.Location, fileName.ToString (), "#A2");
226 a = typeof (int).Assembly;
227 hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
228 Assert.IsTrue (GetModuleFileName (hinstance, fileName,
229 fileName.Capacity) > 0, "#B1");
230 Assert.IsTrue (File.Exists (fileName.ToString ()), "#B3");
231 Assert.AreEqual ("mscorlib.dll", Path.GetFileName (fileName.ToString ()), "#B4");
235 public void GetHINSTANCE_Module_Dynamic ()
237 AssemblyName aname = new AssemblyName ();
240 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
241 aname, AssemblyBuilderAccess.Save,
242 Path.GetTempPath ());
243 ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", false);
245 IntPtr hinstance = Marshal.GetHINSTANCE (mb);
246 Assert.AreEqual (-1, hinstance.ToInt32 ());
250 public void GetHINSTANCE_Module_Null ()
253 Marshal.GetHINSTANCE ((Module) null);
255 } catch (ArgumentNullException ex) {
256 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
257 Assert.IsNull (ex.InnerException, "#3");
258 Assert.IsNotNull (ex.Message, "#4");
259 Assert.AreEqual ("m", ex.ParamName, "#5");
265 public void GetHRForException ()
267 Assert.AreEqual (0, Marshal.GetHRForException (null));
268 Assert.IsTrue (Marshal.GetHRForException (new Exception ()) < 0);
269 Assert.AreEqual (12345, Marshal.GetHRForException (new IOException ("test message", 12345)));
272 [Test] // bug #319009
273 public void StringToHGlobalUni ()
275 IntPtr handle = Marshal.StringToHGlobalUni ("unicode data");
276 string s = Marshal.PtrToStringUni (handle);
277 Assert.AreEqual (12, s.Length, "#1");
279 handle = Marshal.StringToHGlobalUni ("unicode data string");
280 s = Marshal.PtrToStringUni (handle);
281 Assert.AreEqual (19, s.Length, "#2");
285 public void ReadIntByte ()
287 IntPtr ptr = Marshal.AllocHGlobal (4);
289 Marshal.WriteByte (ptr, 0, 0x1);
290 Marshal.WriteByte (ptr, 1, 0x2);
291 Assert.AreEqual (0x1, Marshal.ReadByte (ptr));
292 Assert.AreEqual (0x1, Marshal.ReadByte (ptr, 0));
293 Assert.AreEqual (0x2, Marshal.ReadByte (ptr, 1));
295 Marshal.FreeHGlobal (ptr);
300 public void ReadInt16 ()
302 IntPtr ptr = Marshal.AllocHGlobal (64);
304 Marshal.WriteInt16 (ptr, 0, 0x1234);
305 Marshal.WriteInt16 (ptr, 2, 0x4567);
306 Marshal.WriteInt16 (ptr, 5, 0x4567);
307 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr));
308 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr, 0));
309 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 2));
310 Assert.AreEqual (0x4567, Marshal.ReadInt16 ((ptr + 5)));
311 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 5));
313 Marshal.FreeHGlobal (ptr);
318 public void ReadInt32 ()
320 IntPtr ptr = Marshal.AllocHGlobal (64);
322 Marshal.WriteInt32 (ptr, 0, 0x12345678);
323 Marshal.WriteInt32 (ptr, 4, 0x77654321);
324 Marshal.WriteInt32 (ptr, 10, 0x77654321);
325 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr));
326 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr, 0));
327 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 4));
328 Assert.AreEqual (0x77654321, Marshal.ReadInt32 ((ptr + 10)));
329 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 10));
331 Marshal.FreeHGlobal (ptr);
336 public void ReadInt32_Endian ()
338 IntPtr ptr = Marshal.AllocHGlobal (4);
340 Marshal.WriteByte (ptr, 0, 0x01);
341 Marshal.WriteByte (ptr, 1, 0x02);
342 Marshal.WriteByte (ptr, 2, 0x03);
343 Marshal.WriteByte (ptr, 3, 0x04);
344 // Marshal MUST use the native CPU data
345 if (BitConverter.IsLittleEndian){
346 Assert.AreEqual (0x04030201, Marshal.ReadInt32 (ptr), "ReadInt32");
348 Assert.AreEqual (0x01020304, Marshal.ReadInt32 (ptr), "ReadInt32");
351 Marshal.FreeHGlobal (ptr);
356 public void ReadInt64 ()
358 IntPtr ptr = Marshal.AllocHGlobal (16);
360 Marshal.WriteInt64 (ptr, 0, 0x12345678ABCDEFL);
361 Marshal.WriteInt64 (ptr, 8, 0x87654321ABCDEFL);
362 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr));
363 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr, 0));
364 Assert.AreEqual (0x87654321ABCDEFL, Marshal.ReadInt64 (ptr, 8));
366 Marshal.FreeHGlobal (ptr);
371 [Category ("MobileNotWorking")]
372 public void BSTR_Roundtrip ()
375 IntPtr ptr = Marshal.StringToBSTR (s);
376 string s2 = Marshal.PtrToStringBSTR (ptr);
377 Assert.AreEqual (s, s2, "string");
381 [Category ("MobileNotWorking")]
382 public void StringToBSTRWithNullValues ()
385 string s = String.Empty.PadLeft (size, '\0');
386 Assert.AreEqual (size, s.Length, "Length-1");
388 IntPtr ptr = Marshal.StringToBSTR (s);
390 for (int i = 0; i < size; i += 4)
391 Marshal.WriteInt32 (ptr, i, 0);
393 string s2 = Marshal.PtrToStringBSTR (ptr);
394 Assert.AreEqual (128, s2.Length, "Length-2");
396 Marshal.FreeBSTR (ptr);
401 public void StringToHGlobalAnsiWithNullValues ()
404 string s = String.Empty.PadLeft (size, '\0');
405 Assert.AreEqual (size, s.Length, "Length-1");
407 IntPtr ptr = Marshal.StringToHGlobalAnsi (s);
409 for (int i = 0; i < size; i += 4)
410 Marshal.WriteInt32 (ptr, i, 0);
412 string s2 = Marshal.PtrToStringAnsi (ptr);
413 Assert.AreEqual (0, s2.Length, "Length-2");
415 Marshal.FreeHGlobal (ptr);
420 public void StringToHGlobalAutoWithNullValues ()
423 string s = String.Empty.PadLeft (size, '\0');
424 Assert.AreEqual (size, s.Length, "Length-1");
426 IntPtr ptr = Marshal.StringToHGlobalAuto (s);
428 for (int i = 0; i < size; i += 4)
429 Marshal.WriteInt32 (ptr, i, 0);
431 string s2 = Marshal.PtrToStringAuto (ptr);
432 Assert.AreEqual (0, s2.Length, "Length-2");
434 Marshal.FreeHGlobal (ptr);
439 public void StringToHGlobalUniWithNullValues ()
442 string s = String.Empty.PadLeft (size, '\0');
443 Assert.AreEqual (size, s.Length, "Length-1");
445 IntPtr ptr = Marshal.StringToHGlobalUni (s);
447 for (int i = 0; i < size; i += 4)
448 Marshal.WriteInt32 (ptr, i, 0);
450 string s2 = Marshal.PtrToStringUni (ptr);
451 Assert.AreEqual (0, s2.Length, "Length-2");
453 Marshal.FreeHGlobal (ptr);
458 public void StringToCoTaskMemAnsiWithNullValues ()
461 string s = String.Empty.PadLeft (size, '\0');
462 Assert.AreEqual (size, s.Length, "Length-1");
464 IntPtr ptr = Marshal.StringToCoTaskMemAnsi (s);
466 for (int i = 0; i < size; i += 4)
467 Marshal.WriteInt32 (ptr, i, 0);
469 string s2 = Marshal.PtrToStringAnsi (ptr);
470 Assert.AreEqual (0, s2.Length, "Length-2");
472 Marshal.FreeCoTaskMem (ptr);
477 public void StringToCoTaskMemAutoWithNullValues ()
480 string s = String.Empty.PadLeft (size, '\0');
481 Assert.AreEqual (size, s.Length, "Length-1");
483 IntPtr ptr = Marshal.StringToCoTaskMemAuto (s);
485 for (int i = 0; i < size; i += 4)
486 Marshal.WriteInt32 (ptr, i, 0);
488 string s2 = Marshal.PtrToStringAuto (ptr);
489 Assert.AreEqual (0, s2.Length, "Length-2");
491 Marshal.FreeCoTaskMem (ptr);
496 public void StringToCoTaskMemUniWithNullValues ()
499 string s = String.Empty.PadLeft (size, '\0');
500 Assert.AreEqual (size, s.Length, "Length-1");
502 IntPtr ptr = Marshal.StringToCoTaskMemUni (s);
504 for (int i = 0; i < size; i += 4)
505 Marshal.WriteInt32 (ptr, i, 0);
507 string s2 = Marshal.PtrToStringUni (ptr);
508 Assert.AreEqual (0, s2.Length, "Length-2");
510 Marshal.FreeCoTaskMem (ptr);
513 private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
514 private static char[] PlainText = new char[] { 'a', 'b', 'c' };
515 private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
517 private unsafe SecureString GetSecureString ()
519 fixed (char* p = &PlainText[0]) {
520 return new SecureString (p, PlainText.Length);
525 public void SecureStringToBSTR_Null ()
528 Marshal.SecureStringToBSTR (null);
530 } catch (ArgumentNullException ex) {
531 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
532 Assert.IsNull (ex.InnerException, "#3");
533 Assert.IsNotNull (ex.Message, "#4");
534 Assert.AreEqual ("s", ex.ParamName, "#5");
539 public void SecureStringToBSTR ()
542 SecureString ss = GetSecureString ();
543 IntPtr p = Marshal.SecureStringToBSTR (ss);
545 char[] decrypted = new char[ss.Length];
546 Marshal.Copy (p, decrypted, 0, decrypted.Length);
547 Assert.AreEqual (PlainText, decrypted, "Decrypted");
549 Marshal.ZeroFreeBSTR (p);
550 } catch (NotSupportedException) {
551 Assert.Ignore (NotSupported);
556 public void SecureStringToCoTaskMemAnsi_Null ()
559 Marshal.SecureStringToCoTaskMemAnsi (null);
561 } catch (ArgumentNullException ex) {
562 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
563 Assert.IsNull (ex.InnerException, "#3");
564 Assert.IsNotNull (ex.Message, "#4");
565 Assert.AreEqual ("s", ex.ParamName, "#5");
570 public void SecureStringToCoTaskMemAnsi ()
573 SecureString ss = GetSecureString ();
574 IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
576 byte[] decrypted = new byte[ss.Length];
577 Marshal.Copy (p, decrypted, 0, decrypted.Length);
578 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
580 Marshal.ZeroFreeCoTaskMemAnsi (p);
581 } catch (NotSupportedException) {
582 Assert.Ignore (NotSupported);
587 public void SecureStringToCoTaskMemUnicode_Null ()
590 Marshal.SecureStringToCoTaskMemUnicode (null);
592 } catch (ArgumentNullException ex) {
593 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
594 Assert.IsNull (ex.InnerException, "#3");
595 Assert.IsNotNull (ex.Message, "#4");
596 Assert.AreEqual ("s", ex.ParamName, "#5");
601 public void SecureStringToCoTaskMemUnicode ()
604 SecureString ss = GetSecureString ();
605 IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
607 char[] decrypted = new char[ss.Length];
608 Marshal.Copy (p, decrypted, 0, decrypted.Length);
609 Assert.AreEqual (PlainText, decrypted, "Decrypted");
611 Marshal.ZeroFreeCoTaskMemUnicode (p);
612 } catch (NotSupportedException) {
613 Assert.Ignore (NotSupported);
618 public void SecureStringToGlobalAllocAnsi_Null ()
621 Marshal.SecureStringToGlobalAllocAnsi (null);
623 } catch (ArgumentNullException ex) {
624 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
625 Assert.IsNull (ex.InnerException, "#3");
626 Assert.IsNotNull (ex.Message, "#4");
627 Assert.AreEqual ("s", ex.ParamName, "#5");
632 public void SecureStringToGlobalAllocAnsi ()
635 SecureString ss = GetSecureString ();
636 IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
638 byte[] decrypted = new byte[ss.Length];
639 Marshal.Copy (p, decrypted, 0, decrypted.Length);
640 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
642 Marshal.ZeroFreeGlobalAllocAnsi (p);
643 } catch (NotSupportedException) {
644 Assert.Ignore (NotSupported);
649 public void SecureStringToGlobalAllocUnicode_Null ()
652 Marshal.SecureStringToGlobalAllocUnicode (null);
654 } catch (ArgumentNullException ex) {
655 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
656 Assert.IsNull (ex.InnerException, "#3");
657 Assert.IsNotNull (ex.Message, "#4");
658 Assert.AreEqual ("s", ex.ParamName, "#5");
663 public void SecureStringToGlobalAllocUnicode ()
666 SecureString ss = GetSecureString ();
667 IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
669 char[] decrypted = new char[ss.Length];
670 Marshal.Copy (p, decrypted, 0, decrypted.Length);
671 Assert.AreEqual (PlainText, decrypted, "Decrypted");
673 Marshal.ZeroFreeGlobalAllocUnicode (p);
674 } catch (NotSupportedException) {
675 Assert.Ignore (NotSupported);
681 public void TestGetComSlotForMethodInfo ()
683 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
684 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
685 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
686 Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
688 for (int i = 0; i < 10; i++)
689 Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
693 public void TestGetComSlotForMethod_Method_Null ()
696 Marshal.GetComSlotForMethodInfo (null);
698 } catch (ArgumentNullException ex) {
699 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
700 Assert.IsNull (ex.InnerException, "#3");
701 Assert.IsNotNull (ex.Message, "#4");
702 Assert.AreEqual ("m", ex.ParamName, "#5");
707 public void TestGetComSlotForMethodInfo_Method_NotOnInterface ()
709 MethodInfo m = typeof(TestCoClass).GetMethod ("DoNothing");
711 Marshal.GetComSlotForMethodInfo (m);
713 } catch (ArgumentException ex) {
714 // The MemberInfo must be an interface method
715 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
716 Assert.IsNull (ex.InnerException, "#3");
717 Assert.IsNotNull (ex.Message, "#4");
718 Assert.AreEqual ("m", ex.ParamName, "#5");
723 public void TestPtrToStringAuto ()
725 string input = Guid.NewGuid ().ToString ();
731 if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
733 ptr = Marshal.StringToHGlobalAuto (input);
734 output = Marshal.PtrToStringUni (ptr);
735 output2 = Marshal.PtrToStringUni (ptr, len);
738 ptr = Marshal.StringToHGlobalAuto (input);
739 output = Marshal.PtrToStringAnsi (ptr);
740 output2 = Marshal.PtrToStringAnsi (ptr, len);
744 Assert.AreEqual (input, output, "#1");
745 Assert.AreEqual (input.Substring (0, len), output2, "#2");
747 Marshal.FreeHGlobal (ptr);
752 public void TestGenerateProgIdForType()
756 output = Marshal.GenerateProgIdForType(typeof(TestCoClass));
757 Assert.AreEqual ("MonoTests.System.Runtime.InteropServices.TestCoClass", output, "#1");
759 output = Marshal.GenerateProgIdForType(typeof(TestCoClassWithProgId));
760 Assert.AreEqual ("CoClassWithProgId", output, "#2");
764 public void TestGlobalAlloc ()
766 IntPtr mem = Marshal.AllocHGlobal (100);
767 mem = Marshal.ReAllocHGlobal (mem, (IntPtr) 1000000);
768 Marshal.FreeHGlobal (mem);
772 public void FreeHGlobal ()
774 // clear user doubts on assistly #6749
775 for (int i = 0; i < 1024; i++) {
776 IntPtr p = Marshal.AllocHGlobal (1024 * 1024);
777 Assert.AreNotEqual (IntPtr.Zero, p, i.ToString ());
778 Marshal.FreeHGlobal (p);
782 [StructLayout (LayoutKind.Sequential)]
783 public struct SimpleStruct2 {
789 public void PtrToStructureNull ()
791 Assert.IsNull (Marshal.PtrToStructure (IntPtr.Zero, typeof (SimpleStruct2)));
795 public void TestGetExceptionForHR ()
797 const int E_OUTOFMEMORY = unchecked ((int) 0x8007000E);
798 const int E_INVALIDARG = unchecked ((int) 0X80070057);
800 Exception ex = Marshal.GetExceptionForHR (E_OUTOFMEMORY);
801 Assert.AreEqual (typeof (OutOfMemoryException), ex.GetType (), "E_OUTOFMEMORY");
803 ex = Marshal.GetExceptionForHR (E_INVALIDARG);
804 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
808 return (Type.GetType ("System.MonoType", false) != null);
813 [DllImport ("kernel32.dll", SetLastError = true)]
815 static extern uint GetModuleFileName (
819 StringBuilder lpFilename,
821 [MarshalAs (UnmanagedType.U4)]
826 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
827 public class FourByteStruct
829 public UInt16 value1;
830 public UInt16 value2;
833 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
834 public class ByteArrayFourByteStruct : FourByteStruct
836 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
840 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
841 public class SingleByteStruct
846 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
847 public class ByteArraySingleByteStruct : SingleByteStruct
849 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
850 public byte[] array1;
854 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
855 public class ByteArraySingleByteChildStruct : ByteArraySingleByteStruct
857 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
858 public byte[] array2;
862 public void CheckByteArrayFourByteStruct()
864 ByteArrayFourByteStruct myStruct = new ByteArrayFourByteStruct
865 { value1 = 42, value2 = 53, array = Encoding.UTF8.GetBytes( "Hello" ) };
867 byte[] buffer = Serialize (myStruct);
869 UInt16 value1 = BitConverter.ToUInt16 (buffer, 0);
870 UInt16 value2 = BitConverter.ToUInt16 (buffer, 2);
871 string array = Encoding.UTF8.GetString (buffer, 4, 5);
873 Assert.AreEqual((UInt16)42, value1);
874 Assert.AreEqual((UInt16)53, value2);
875 Assert.AreEqual ("Hello", array);
879 public void CheckByteArraySingleByteChildStruct()
881 ByteArraySingleByteChildStruct myStruct = new ByteArraySingleByteChildStruct
882 { value1 = 42, array1 = Encoding.UTF8.GetBytes( "Hello" ), value2 = 53, array2 = Encoding.UTF8.GetBytes( "World" ) };
884 byte[] array = Serialize (myStruct);
886 byte value1 = array [0];
887 string array1 = Encoding.UTF8.GetString (array, 1, 5);
888 byte value2 = array [6];
889 string array2 = Encoding.UTF8.GetString (array, 7, 5);
891 Assert.AreEqual((byte)42, value1);
892 Assert.AreEqual ("Hello", array1);
893 Assert.AreEqual((byte)53, value2);
894 Assert.AreEqual ("World", array2);
897 [StructLayout(LayoutKind.Sequential, Pack = 1)]
898 public struct FiveByteStruct
900 public uint uIntField;
901 public byte byteField;
904 [StructLayout(LayoutKind.Sequential, Pack = 1)]
907 public ushort firstUShortField;
908 public ushort secondUShortField;
911 [StructLayout(LayoutKind.Sequential, Pack = 1)]
912 public class Derived : Base
914 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
915 public FiveByteStruct[] arrayField;
919 public void CheckPtrToStructureWithFixedArrayAndBaseClassFields()
921 const int arraySize = 6;
922 var derived = new Derived
924 arrayField = new FiveByteStruct[arraySize],
925 firstUShortField = 42,
926 secondUShortField = 43
929 for (var i = 0; i < arraySize; ++i)
931 derived.arrayField[i].byteField = (byte)i;
932 derived.arrayField[i].uIntField = (uint)i * 10;
935 var array = Serialize(derived);
936 var deserializedDerived = Deserialize<Derived>(array);
938 Assert.AreEqual(derived.firstUShortField, deserializedDerived.firstUShortField, "The firstUShortField differs, which is not expected.");
939 Assert.AreEqual(derived.secondUShortField, deserializedDerived.secondUShortField, "The secondUShortField differs, which is not expected.");
941 for (var i = 0; i < arraySize; ++i)
943 Assert.AreEqual(derived.arrayField[i].byteField, deserializedDerived.arrayField[i].byteField, string.Format("The byteField at index {0} differs, which is not expected.", i));
944 Assert.AreEqual(derived.arrayField[i].uIntField, deserializedDerived.arrayField[i].uIntField, string.Format("The uIntField at index {0} differs, which is not expected.", i));
948 public static byte[] Serialize( object obj )
950 int nTypeSize = Marshal.SizeOf( obj );
951 byte[] arrBuffer = new byte[nTypeSize];
953 GCHandle hGCHandle = GCHandle.Alloc( arrBuffer, GCHandleType.Pinned );
954 IntPtr pBuffer = hGCHandle.AddrOfPinnedObject();
955 Marshal.StructureToPtr( obj, pBuffer, false );
961 public static T Deserialize<T>(byte[] buffer)
963 var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
964 var pBuffer = handle.AddrOfPinnedObject();
965 var objResult = (T)Marshal.PtrToStructure(pBuffer, typeof(T));
973 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
974 interface ITestDefault
980 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
981 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
982 interface ITestDispatch
988 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
989 [InterfaceType(ComInterfaceType.InterfaceIsDual)]
996 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
997 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
998 interface ITestUnknown
1004 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1005 interface ITestInterface
1019 public class TestCoClass : ITestDispatch
1021 public void DoNothing ()
1026 [ProgId("CoClassWithProgId")]
1027 public class TestCoClassWithProgId : ITestDispatch
1029 public void DoNothing ()