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");
158 readonly String[] TestStrings = new String[] {
161 "A", //Single character string
162 "This is a very long string as it repeats itself. " +
163 "This is a very long string as it repeats itself. " +
164 "This is a very long string as it repeats itself. " +
165 "This is a very long string as it repeats itself. " +
166 "This is a very long string as it repeats itself. " +
167 "This is a very long string as it repeats itself. " +
168 "This is a very long string as it repeats itself. " +
169 "This is a very long string as it repeats itself. " +
170 "This is a very long string as it repeats itself. " +
171 "This is a very long string as it repeats itself. " +
172 "This is a very long string as it repeats itself. " +
173 "This is a very long string as it repeats itself. " +
174 "This is a very long string as it repeats itself.",
175 "This \n is \n a \n multiline \n string",
176 "This \0 is \0 a \0 string \0 with \0 nulls",
183 public unsafe void PtrToStringUTF8_Test ()
186 foreach (String srcString in TestStrings)
189 // we assume string null terminated
190 if (srcString.Contains("\0"))
193 IntPtr ptrString = Marshal.StringToAllocatedMemoryUTF8(srcString);
194 string retString = Marshal.PtrToStringUTF8(ptrString);
196 Assert.AreEqual (srcString, retString, "#" + i);
197 if (srcString.Length > 0)
199 string retString2 = Marshal.PtrToStringUTF8(ptrString, srcString.Length - 1);
200 Assert.AreEqual (srcString.Substring(0, srcString.Length - 1), retString2, "#s" + i);
202 Marshal.FreeHGlobal(ptrString);
207 public unsafe void UnsafeAddrOfPinnedArrayElement ()
209 short[] sarr = new short [5];
212 IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement (sarr, 2);
213 Assert.AreEqual (3, *(short*) ptr.ToPointer ());
217 public void AllocHGlobalZeroSize ()
219 IntPtr ptr = Marshal.AllocHGlobal (0);
220 Assert.IsTrue (ptr != IntPtr.Zero);
221 Marshal.FreeHGlobal (ptr);
225 public void AllocCoTaskMemZeroSize ()
227 IntPtr ptr = Marshal.AllocCoTaskMem (0);
228 Assert.IsTrue (ptr != IntPtr.Zero);
229 Marshal.FreeCoTaskMem (ptr);
236 public static char d;
241 public void OffsetOf_FieldName_Static ()
244 Marshal.OffsetOf (typeof (Foo), "b");
246 } catch (ArgumentException ex) {
247 // Field passed in is not a marshaled member of
248 // the type '...MarshalTest+Foo'
249 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
250 Assert.IsNull (ex.InnerException, "#3");
251 Assert.IsNotNull (ex.Message, "#4");
252 Assert.AreEqual ("fieldName", ex.ParamName, "#5");
257 public void GetHINSTANCE ()
260 Assert.Ignore ("GetHINSTANCE only applies to .NET on Windows.");
264 StringBuilder fileName;
266 fileName = new StringBuilder (255);
267 a = Assembly.GetExecutingAssembly ();
268 hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
269 Assert.IsTrue (GetModuleFileName (hinstance, fileName,
270 fileName.Capacity) > 0, "#A1");
271 Assert.AreEqual (a.Location, fileName.ToString (), "#A2");
274 a = typeof (int).Assembly;
275 hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
276 Assert.IsTrue (GetModuleFileName (hinstance, fileName,
277 fileName.Capacity) > 0, "#B1");
278 Assert.IsTrue (File.Exists (fileName.ToString ()), "#B3");
279 Assert.AreEqual ("mscorlib.dll", Path.GetFileName (fileName.ToString ()), "#B4");
283 public void GetHINSTANCE_Module_Dynamic ()
285 AssemblyName aname = new AssemblyName ();
288 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
289 aname, AssemblyBuilderAccess.Save,
290 Path.GetTempPath ());
291 ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", false);
293 IntPtr hinstance = Marshal.GetHINSTANCE (mb);
294 Assert.AreEqual (-1, hinstance.ToInt32 ());
298 public void GetHINSTANCE_Module_Null ()
301 Marshal.GetHINSTANCE ((Module) null);
303 } catch (ArgumentNullException ex) {
304 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
305 Assert.IsNull (ex.InnerException, "#3");
306 Assert.IsNotNull (ex.Message, "#4");
307 Assert.AreEqual ("m", ex.ParamName, "#5");
313 public void GetHRForException ()
315 Assert.AreEqual (0, Marshal.GetHRForException (null));
316 Assert.IsTrue (Marshal.GetHRForException (new Exception ()) < 0);
317 Assert.AreEqual (12345, Marshal.GetHRForException (new IOException ("test message", 12345)));
320 [Test] // bug #319009
321 public void StringToHGlobalUni ()
323 IntPtr handle = Marshal.StringToHGlobalUni ("unicode data");
324 string s = Marshal.PtrToStringUni (handle);
325 Assert.AreEqual (12, s.Length, "#1");
327 handle = Marshal.StringToHGlobalUni ("unicode data string");
328 s = Marshal.PtrToStringUni (handle);
329 Assert.AreEqual (19, s.Length, "#2");
333 public void ReadIntByte ()
335 IntPtr ptr = Marshal.AllocHGlobal (4);
337 Marshal.WriteByte (ptr, 0, 0x1);
338 Marshal.WriteByte (ptr, 1, 0x2);
339 Assert.AreEqual (0x1, Marshal.ReadByte (ptr));
340 Assert.AreEqual (0x1, Marshal.ReadByte (ptr, 0));
341 Assert.AreEqual (0x2, Marshal.ReadByte (ptr, 1));
343 Marshal.FreeHGlobal (ptr);
348 public void ReadInt16 ()
350 IntPtr ptr = Marshal.AllocHGlobal (64);
352 Marshal.WriteInt16 (ptr, 0, 0x1234);
353 Marshal.WriteInt16 (ptr, 2, 0x4567);
354 Marshal.WriteInt16 (ptr, 5, 0x4567);
355 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr));
356 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr, 0));
357 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 2));
358 Assert.AreEqual (0x4567, Marshal.ReadInt16 ((ptr + 5)));
359 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 5));
361 Marshal.FreeHGlobal (ptr);
366 public void ReadInt32 ()
368 IntPtr ptr = Marshal.AllocHGlobal (64);
370 Marshal.WriteInt32 (ptr, 0, 0x12345678);
371 Marshal.WriteInt32 (ptr, 4, 0x77654321);
372 Marshal.WriteInt32 (ptr, 10, 0x77654321);
373 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr));
374 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr, 0));
375 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 4));
376 Assert.AreEqual (0x77654321, Marshal.ReadInt32 ((ptr + 10)));
377 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 10));
379 Marshal.FreeHGlobal (ptr);
384 public void ReadInt32_Endian ()
386 IntPtr ptr = Marshal.AllocHGlobal (4);
388 Marshal.WriteByte (ptr, 0, 0x01);
389 Marshal.WriteByte (ptr, 1, 0x02);
390 Marshal.WriteByte (ptr, 2, 0x03);
391 Marshal.WriteByte (ptr, 3, 0x04);
392 // Marshal MUST use the native CPU data
393 if (BitConverter.IsLittleEndian){
394 Assert.AreEqual (0x04030201, Marshal.ReadInt32 (ptr), "ReadInt32");
396 Assert.AreEqual (0x01020304, Marshal.ReadInt32 (ptr), "ReadInt32");
399 Marshal.FreeHGlobal (ptr);
404 public void ReadInt64 ()
406 IntPtr ptr = Marshal.AllocHGlobal (16);
408 Marshal.WriteInt64 (ptr, 0, 0x12345678ABCDEFL);
409 Marshal.WriteInt64 (ptr, 8, 0x87654321ABCDEFL);
410 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr));
411 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr, 0));
412 Assert.AreEqual (0x87654321ABCDEFL, Marshal.ReadInt64 (ptr, 8));
414 Marshal.FreeHGlobal (ptr);
419 [Category ("MobileNotWorking")]
420 public void BSTR_Roundtrip ()
423 IntPtr ptr = Marshal.StringToBSTR (s);
424 string s2 = Marshal.PtrToStringBSTR (ptr);
425 Assert.AreEqual (s, s2, "string");
429 [Category ("MobileNotWorking")]
430 public void StringToBSTRWithNullValues ()
433 string s = String.Empty.PadLeft (size, '\0');
434 Assert.AreEqual (size, s.Length, "Length-1");
436 IntPtr ptr = Marshal.StringToBSTR (s);
438 for (int i = 0; i < size; i += 4)
439 Marshal.WriteInt32 (ptr, i, 0);
441 string s2 = Marshal.PtrToStringBSTR (ptr);
442 Assert.AreEqual (128, s2.Length, "Length-2");
444 Marshal.FreeBSTR (ptr);
449 public void StringToHGlobalAnsiWithNullValues ()
452 string s = String.Empty.PadLeft (size, '\0');
453 Assert.AreEqual (size, s.Length, "Length-1");
455 IntPtr ptr = Marshal.StringToHGlobalAnsi (s);
457 for (int i = 0; i < size; i += 4)
458 Marshal.WriteInt32 (ptr, i, 0);
460 string s2 = Marshal.PtrToStringAnsi (ptr);
461 Assert.AreEqual (0, s2.Length, "Length-2");
463 Marshal.FreeHGlobal (ptr);
468 public void StringToHGlobalAutoWithNullValues ()
471 string s = String.Empty.PadLeft (size, '\0');
472 Assert.AreEqual (size, s.Length, "Length-1");
474 IntPtr ptr = Marshal.StringToHGlobalAuto (s);
476 for (int i = 0; i < size; i += 4)
477 Marshal.WriteInt32 (ptr, i, 0);
479 string s2 = Marshal.PtrToStringAuto (ptr);
480 Assert.AreEqual (0, s2.Length, "Length-2");
482 Marshal.FreeHGlobal (ptr);
487 public void StringToHGlobalUniWithNullValues ()
490 string s = String.Empty.PadLeft (size, '\0');
491 Assert.AreEqual (size, s.Length, "Length-1");
493 IntPtr ptr = Marshal.StringToHGlobalUni (s);
495 for (int i = 0; i < size; i += 4)
496 Marshal.WriteInt32 (ptr, i, 0);
498 string s2 = Marshal.PtrToStringUni (ptr);
499 Assert.AreEqual (0, s2.Length, "Length-2");
501 Marshal.FreeHGlobal (ptr);
506 public void StringToCoTaskMemAnsiWithNullValues ()
509 string s = String.Empty.PadLeft (size, '\0');
510 Assert.AreEqual (size, s.Length, "Length-1");
512 IntPtr ptr = Marshal.StringToCoTaskMemAnsi (s);
514 for (int i = 0; i < size; i += 4)
515 Marshal.WriteInt32 (ptr, i, 0);
517 string s2 = Marshal.PtrToStringAnsi (ptr);
518 Assert.AreEqual (0, s2.Length, "Length-2");
520 Marshal.FreeCoTaskMem (ptr);
525 public void StringToCoTaskMemAutoWithNullValues ()
528 string s = String.Empty.PadLeft (size, '\0');
529 Assert.AreEqual (size, s.Length, "Length-1");
531 IntPtr ptr = Marshal.StringToCoTaskMemAuto (s);
533 for (int i = 0; i < size; i += 4)
534 Marshal.WriteInt32 (ptr, i, 0);
536 string s2 = Marshal.PtrToStringAuto (ptr);
537 Assert.AreEqual (0, s2.Length, "Length-2");
539 Marshal.FreeCoTaskMem (ptr);
544 public void StringToCoTaskMemUniWithNullValues ()
547 string s = String.Empty.PadLeft (size, '\0');
548 Assert.AreEqual (size, s.Length, "Length-1");
550 IntPtr ptr = Marshal.StringToCoTaskMemUni (s);
552 for (int i = 0; i < size; i += 4)
553 Marshal.WriteInt32 (ptr, i, 0);
555 string s2 = Marshal.PtrToStringUni (ptr);
556 Assert.AreEqual (0, s2.Length, "Length-2");
558 Marshal.FreeCoTaskMem (ptr);
561 private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
562 private static char[] PlainText = new char[] { 'a', 'b', 'c' };
563 private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
565 private unsafe SecureString GetSecureString ()
567 fixed (char* p = &PlainText[0]) {
568 return new SecureString (p, PlainText.Length);
573 public void SecureStringToBSTR_Null ()
576 Marshal.SecureStringToBSTR (null);
578 } catch (ArgumentNullException ex) {
579 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
580 Assert.IsNull (ex.InnerException, "#3");
581 Assert.IsNotNull (ex.Message, "#4");
582 Assert.AreEqual ("s", ex.ParamName, "#5");
587 public void SecureStringToBSTR ()
590 SecureString ss = GetSecureString ();
591 IntPtr p = Marshal.SecureStringToBSTR (ss);
593 char[] decrypted = new char[ss.Length];
594 Marshal.Copy (p, decrypted, 0, decrypted.Length);
595 Assert.AreEqual (PlainText, decrypted, "Decrypted");
597 Marshal.ZeroFreeBSTR (p);
598 } catch (NotSupportedException) {
599 Assert.Ignore (NotSupported);
604 public void SecureStringToCoTaskMemAnsi_Null ()
607 Marshal.SecureStringToCoTaskMemAnsi (null);
609 } catch (ArgumentNullException ex) {
610 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
611 Assert.IsNull (ex.InnerException, "#3");
612 Assert.IsNotNull (ex.Message, "#4");
613 Assert.AreEqual ("s", ex.ParamName, "#5");
618 public void SecureStringToCoTaskMemAnsi ()
621 SecureString ss = GetSecureString ();
622 IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
624 byte[] decrypted = new byte[ss.Length];
625 Marshal.Copy (p, decrypted, 0, decrypted.Length);
626 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
628 Marshal.ZeroFreeCoTaskMemAnsi (p);
629 } catch (NotSupportedException) {
630 Assert.Ignore (NotSupported);
635 public void SecureStringToCoTaskMemUnicode_Null ()
638 Marshal.SecureStringToCoTaskMemUnicode (null);
640 } catch (ArgumentNullException ex) {
641 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
642 Assert.IsNull (ex.InnerException, "#3");
643 Assert.IsNotNull (ex.Message, "#4");
644 Assert.AreEqual ("s", ex.ParamName, "#5");
649 public void SecureStringToCoTaskMemUnicode ()
652 SecureString ss = GetSecureString ();
653 IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
655 char[] decrypted = new char[ss.Length];
656 Marshal.Copy (p, decrypted, 0, decrypted.Length);
657 Assert.AreEqual (PlainText, decrypted, "Decrypted");
659 Marshal.ZeroFreeCoTaskMemUnicode (p);
660 } catch (NotSupportedException) {
661 Assert.Ignore (NotSupported);
666 public void SecureStringToGlobalAllocAnsi_Null ()
669 Marshal.SecureStringToGlobalAllocAnsi (null);
671 } catch (ArgumentNullException ex) {
672 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
673 Assert.IsNull (ex.InnerException, "#3");
674 Assert.IsNotNull (ex.Message, "#4");
675 Assert.AreEqual ("s", ex.ParamName, "#5");
680 public void SecureStringToGlobalAllocAnsi ()
683 SecureString ss = GetSecureString ();
684 IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
686 byte[] decrypted = new byte[ss.Length];
687 Marshal.Copy (p, decrypted, 0, decrypted.Length);
688 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
690 Marshal.ZeroFreeGlobalAllocAnsi (p);
691 } catch (NotSupportedException) {
692 Assert.Ignore (NotSupported);
697 public void SecureStringToGlobalAllocUnicode_Null ()
700 Marshal.SecureStringToGlobalAllocUnicode (null);
702 } catch (ArgumentNullException ex) {
703 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
704 Assert.IsNull (ex.InnerException, "#3");
705 Assert.IsNotNull (ex.Message, "#4");
706 Assert.AreEqual ("s", ex.ParamName, "#5");
711 public void SecureStringToGlobalAllocUnicode ()
714 SecureString ss = GetSecureString ();
715 IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
717 char[] decrypted = new char[ss.Length];
718 Marshal.Copy (p, decrypted, 0, decrypted.Length);
719 Assert.AreEqual (PlainText, decrypted, "Decrypted");
721 Marshal.ZeroFreeGlobalAllocUnicode (p);
722 } catch (NotSupportedException) {
723 Assert.Ignore (NotSupported);
729 public void TestGetComSlotForMethodInfo ()
731 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
732 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
733 Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
734 Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
736 for (int i = 0; i < 10; i++)
737 Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
741 public void TestGetComSlotForMethod_Method_Null ()
744 Marshal.GetComSlotForMethodInfo (null);
746 } catch (ArgumentNullException ex) {
747 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
748 Assert.IsNull (ex.InnerException, "#3");
749 Assert.IsNotNull (ex.Message, "#4");
750 Assert.AreEqual ("m", ex.ParamName, "#5");
755 public void TestGetComSlotForMethodInfo_Method_NotOnInterface ()
757 MethodInfo m = typeof(TestCoClass).GetMethod ("DoNothing");
759 Marshal.GetComSlotForMethodInfo (m);
761 } catch (ArgumentException ex) {
762 // The MemberInfo must be an interface method
763 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
764 Assert.IsNull (ex.InnerException, "#3");
765 Assert.IsNotNull (ex.Message, "#4");
766 Assert.AreEqual ("m", ex.ParamName, "#5");
771 public void TestPtrToStringAuto ()
773 string input = Guid.NewGuid ().ToString ();
779 if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
781 ptr = Marshal.StringToHGlobalAuto (input);
782 output = Marshal.PtrToStringUni (ptr);
783 output2 = Marshal.PtrToStringUni (ptr, len);
786 ptr = Marshal.StringToHGlobalAuto (input);
787 output = Marshal.PtrToStringAnsi (ptr);
788 output2 = Marshal.PtrToStringAnsi (ptr, len);
792 Assert.AreEqual (input, output, "#1");
793 Assert.AreEqual (input.Substring (0, len), output2, "#2");
795 Marshal.FreeHGlobal (ptr);
800 public void TestGenerateProgIdForType()
804 output = Marshal.GenerateProgIdForType(typeof(TestCoClass));
805 Assert.AreEqual ("MonoTests.System.Runtime.InteropServices.TestCoClass", output, "#1");
807 output = Marshal.GenerateProgIdForType(typeof(TestCoClassWithProgId));
808 Assert.AreEqual ("CoClassWithProgId", output, "#2");
812 public void TestGlobalAlloc ()
814 IntPtr mem = Marshal.AllocHGlobal (100);
815 mem = Marshal.ReAllocHGlobal (mem, (IntPtr) 1000000);
816 Marshal.FreeHGlobal (mem);
820 public void FreeHGlobal ()
822 // clear user doubts on assistly #6749
823 for (int i = 0; i < 1024; i++) {
824 IntPtr p = Marshal.AllocHGlobal (1024 * 1024);
825 Assert.AreNotEqual (IntPtr.Zero, p, i.ToString ());
826 Marshal.FreeHGlobal (p);
830 [StructLayout (LayoutKind.Sequential)]
831 public struct SimpleStruct2 {
837 public void PtrToStructureNull ()
839 Assert.IsNull (Marshal.PtrToStructure (IntPtr.Zero, typeof (SimpleStruct2)));
843 public void TestGetExceptionForHR ()
845 const int E_OUTOFMEMORY = unchecked ((int) 0x8007000E);
846 const int E_INVALIDARG = unchecked ((int) 0X80070057);
848 Exception ex = Marshal.GetExceptionForHR (E_OUTOFMEMORY);
849 Assert.AreEqual (typeof (OutOfMemoryException), ex.GetType (), "E_OUTOFMEMORY");
851 ex = Marshal.GetExceptionForHR (E_INVALIDARG);
852 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
856 return (Type.GetType ("System.MonoType", false) != null);
861 [DllImport ("kernel32.dll", SetLastError = true)]
863 static extern uint GetModuleFileName (
867 StringBuilder lpFilename,
869 [MarshalAs (UnmanagedType.U4)]
874 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
875 public class FourByteStruct
877 public UInt16 value1;
878 public UInt16 value2;
881 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
882 public class ByteArrayFourByteStruct : FourByteStruct
884 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
888 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
889 public class SingleByteStruct
894 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
895 public class ByteArraySingleByteStruct : SingleByteStruct
897 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
898 public byte[] array1;
902 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
903 public class ByteArraySingleByteChildStruct : ByteArraySingleByteStruct
905 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
906 public byte[] array2;
910 public void CheckByteArrayFourByteStruct()
912 ByteArrayFourByteStruct myStruct = new ByteArrayFourByteStruct
913 { value1 = 42, value2 = 53, array = Encoding.UTF8.GetBytes( "Hello" ) };
915 byte[] buffer = Serialize (myStruct);
917 UInt16 value1 = BitConverter.ToUInt16 (buffer, 0);
918 UInt16 value2 = BitConverter.ToUInt16 (buffer, 2);
919 string array = Encoding.UTF8.GetString (buffer, 4, 5);
921 Assert.AreEqual((UInt16)42, value1);
922 Assert.AreEqual((UInt16)53, value2);
923 Assert.AreEqual ("Hello", array);
927 public void CheckByteArraySingleByteChildStruct()
929 ByteArraySingleByteChildStruct myStruct = new ByteArraySingleByteChildStruct
930 { value1 = 42, array1 = Encoding.UTF8.GetBytes( "Hello" ), value2 = 53, array2 = Encoding.UTF8.GetBytes( "World" ) };
932 byte[] array = Serialize (myStruct);
934 byte value1 = array [0];
935 string array1 = Encoding.UTF8.GetString (array, 1, 5);
936 byte value2 = array [6];
937 string array2 = Encoding.UTF8.GetString (array, 7, 5);
939 Assert.AreEqual((byte)42, value1);
940 Assert.AreEqual ("Hello", array1);
941 Assert.AreEqual((byte)53, value2);
942 Assert.AreEqual ("World", array2);
945 [StructLayout(LayoutKind.Sequential, Pack = 1)]
946 public struct FiveByteStruct
948 public uint uIntField;
949 public byte byteField;
952 [StructLayout(LayoutKind.Sequential, Pack = 1)]
955 public ushort firstUShortField;
956 public ushort secondUShortField;
959 [StructLayout(LayoutKind.Sequential, Pack = 1)]
960 public class Derived : Base
962 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
963 public FiveByteStruct[] arrayField;
967 public void CheckPtrToStructureWithFixedArrayAndBaseClassFields()
969 const int arraySize = 6;
970 var derived = new Derived
972 arrayField = new FiveByteStruct[arraySize],
973 firstUShortField = 42,
974 secondUShortField = 43
977 for (var i = 0; i < arraySize; ++i)
979 derived.arrayField[i].byteField = (byte)i;
980 derived.arrayField[i].uIntField = (uint)i * 10;
983 var array = Serialize(derived);
984 var deserializedDerived = Deserialize<Derived>(array);
986 Assert.AreEqual(derived.firstUShortField, deserializedDerived.firstUShortField, "The firstUShortField differs, which is not expected.");
987 Assert.AreEqual(derived.secondUShortField, deserializedDerived.secondUShortField, "The secondUShortField differs, which is not expected.");
989 for (var i = 0; i < arraySize; ++i)
991 Assert.AreEqual(derived.arrayField[i].byteField, deserializedDerived.arrayField[i].byteField, string.Format("The byteField at index {0} differs, which is not expected.", i));
992 Assert.AreEqual(derived.arrayField[i].uIntField, deserializedDerived.arrayField[i].uIntField, string.Format("The uIntField at index {0} differs, which is not expected.", i));
996 public static byte[] Serialize( object obj )
998 int nTypeSize = Marshal.SizeOf( obj );
999 byte[] arrBuffer = new byte[nTypeSize];
1001 GCHandle hGCHandle = GCHandle.Alloc( arrBuffer, GCHandleType.Pinned );
1002 IntPtr pBuffer = hGCHandle.AddrOfPinnedObject();
1003 Marshal.StructureToPtr( obj, pBuffer, false );
1009 public static T Deserialize<T>(byte[] buffer)
1011 var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
1012 var pBuffer = handle.AddrOfPinnedObject();
1013 var objResult = (T)Marshal.PtrToStructure(pBuffer, typeof(T));
1021 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1022 interface ITestDefault
1028 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1029 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
1030 interface ITestDispatch
1036 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1037 [InterfaceType(ComInterfaceType.InterfaceIsDual)]
1044 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1045 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
1046 interface ITestUnknown
1052 [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
1053 interface ITestInterface
1067 public class TestCoClass : ITestDispatch
1069 public void DoNothing ()
1074 [ProgId("CoClassWithProgId")]
1075 public class TestCoClassWithProgId : ITestDispatch
1077 public void DoNothing ()