Xamarin Public Jenkins (auto-signing) 0875d0d9cd Imported Upstream version 5.16.0.160
Former-commit-id: 090371aae4deb2cffdeada14f23b6a47fbe7f087
2018-09-15 08:20:41 +00:00

1090 lines
29 KiB
C#

//
// System.Runtime.InteropServices.Marshal Test Cases
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
// Sebastien Pouliot <sebastien@ximian.com>
//
// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
//
using NUnit.Framework;
using System;
using System.IO;
using System.Reflection;
#if !MOBILE
using System.Reflection.Emit;
#endif
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace MonoTests.System.Runtime.InteropServices
{
[TestFixture]
public class MarshalTest
{
[StructLayout (LayoutKind.Sequential)]
class ClsSequential {
public int field;
}
public class ClsNoLayout {
public int field;
}
[StructLayout (LayoutKind.Explicit)]
class ClsExplicit {
[FieldOffset (0)] public int field;
}
[StructLayout (LayoutKind.Sequential)]
struct StrSequential {
public int field;
}
struct StrNoLayout {
public int field;
}
[StructLayout (LayoutKind.Explicit)]
struct StrExplicit {
[FieldOffset (0)] public int field;
}
[Test]
public void SizeOf_Class_LayoutSequential ()
{
Marshal.SizeOf (typeof (ClsSequential));
}
[Test]
public void SizeOf_Class_LayoutNotSet ()
{
try {
Marshal.SizeOf (typeof (ClsNoLayout));
Assert.Fail ("#1");
} catch (ArgumentException ex) {
// Type '...MarshalTest+ClsNoLayout' cannot be
// marshaled as an unmanaged structure; no
// meaningful size or offset can be computed
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
}
}
[Test]
public void SizeOf_Class_LayoutExplicit ()
{
Marshal.SizeOf (typeof (ClsExplicit));
}
[Test]
public void SizeOf_Struct_LayoutSequential ()
{
Marshal.SizeOf (typeof (StrSequential));
}
[Test]
public void SizeOf_Struct_LayoutNotSet ()
{
Marshal.SizeOf (typeof (StrNoLayout));
}
[Test]
public void SizeOf_Struct_LayoutExplicit ()
{
Marshal.SizeOf (typeof (StrExplicit));
}
[Test]
public void SizeOf_Array ()
{
try {
Marshal.SizeOf (typeof (string []));
Assert.Fail ("#1");
} catch (ArgumentException ex) {
// Type 'System.String[]' cannot be marshaled
// as an unmanaged structure; no meaningful
// size or offset can be computed
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
}
}
[Test]
public unsafe void Sizeof_Pointer ()
{
int size = Marshal.SizeOf (typeof (char*));
Assert.IsTrue (size == 4 || size == 8);
}
[Test]
public unsafe void Sizeof_Void ()
{
int size = Marshal.SizeOf (typeof (void));
Assert.AreEqual (1, size);
}
[Test]
public void PtrToStringWithNull ()
{
Assert.IsNull (Marshal.PtrToStringAnsi (IntPtr.Zero), "A");
Assert.IsNull (Marshal.PtrToStringUni (IntPtr.Zero), "C");
}
[Test]
public void PtrToStringAnsi_Ptr_Zero ()
{
try {
Marshal.PtrToStringAnsi (IntPtr.Zero, 0);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("ptr", ex.ParamName, "#5");
}
}
[Test]
public void PtrToStringWithUni_Ptr_Zero ()
{
try {
Marshal.PtrToStringUni (IntPtr.Zero, 0);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("ptr", ex.ParamName, "#5");
}
}
readonly String[] TestStrings = new String[] {
"", //Empty String
"Test String",
"A", //Single character string
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself. " +
"This is a very long string as it repeats itself.",
"This \n is \n a \n multiline \n string",
"This \0 is \0 a \0 string \0 with \0 nulls",
"\0string",
"string\0",
"\0\0\0\0\0\0\0\0"
};
[Test]
public unsafe void PtrToStringUTF8_Test ()
{
int i = 0;
foreach (String srcString in TestStrings)
{
i++;
// we assume string null terminated
if (srcString.Contains("\0"))
continue;
IntPtr ptrString = Marshal.StringToAllocatedMemoryUTF8(srcString);
string retString = Marshal.PtrToStringUTF8(ptrString);
Assert.AreEqual (srcString, retString, "#" + i);
if (srcString.Length > 0)
{
string retString2 = Marshal.PtrToStringUTF8(ptrString, srcString.Length - 1);
Assert.AreEqual (srcString.Substring(0, srcString.Length - 1), retString2, "#s" + i);
}
Marshal.FreeHGlobal(ptrString);
}
}
[Test]
public unsafe void UnsafeAddrOfPinnedArrayElement ()
{
short[] sarr = new short [5];
sarr [2] = 3;
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement (sarr, 2);
Assert.AreEqual (3, *(short*) ptr.ToPointer ());
}
[Test]
public void AllocHGlobalZeroSize ()
{
IntPtr ptr = Marshal.AllocHGlobal (0);
Assert.IsTrue (ptr != IntPtr.Zero);
Marshal.FreeHGlobal (ptr);
}
[Test]
public void AllocCoTaskMemZeroSize ()
{
IntPtr ptr = Marshal.AllocCoTaskMem (0);
Assert.IsTrue (ptr != IntPtr.Zero);
Marshal.FreeCoTaskMem (ptr);
}
public struct Foo {
public int a;
public static int b;
public long c;
public static char d;
public int e;
}
[Test]
public void OffsetOf_FieldName_Static ()
{
try {
Marshal.OffsetOf (typeof (Foo), "b");
Assert.Fail ("#1");
} catch (ArgumentException ex) {
// Field passed in is not a marshaled member of
// the type '...MarshalTest+Foo'
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("fieldName", ex.ParamName, "#5");
}
}
#if !MOBILE
[Test]
public void GetHINSTANCE ()
{
if (RunningOnMono)
Assert.Ignore ("GetHINSTANCE only applies to .NET on Windows.");
Assembly a;
IntPtr hinstance;
StringBuilder fileName;
fileName = new StringBuilder (255);
a = Assembly.GetExecutingAssembly ();
hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
Assert.IsTrue (GetModuleFileName (hinstance, fileName,
fileName.Capacity) > 0, "#A1");
Assert.AreEqual (a.Location, fileName.ToString (), "#A2");
fileName.Length = 0;
a = typeof (int).Assembly;
hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
Assert.IsTrue (GetModuleFileName (hinstance, fileName,
fileName.Capacity) > 0, "#B1");
Assert.IsTrue (File.Exists (fileName.ToString ()), "#B3");
Assert.AreEqual ("mscorlib.dll", Path.GetFileName (fileName.ToString ()), "#B4");
}
[Test]
public void GetHINSTANCE_Module_Dynamic ()
{
AssemblyName aname = new AssemblyName ();
aname.Name = "foo";
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
aname, AssemblyBuilderAccess.Save,
Path.GetTempPath ());
ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", false);
IntPtr hinstance = Marshal.GetHINSTANCE (mb);
Assert.AreEqual (-1, hinstance.ToInt32 ());
}
[Test]
public void GetHINSTANCE_Module_Null ()
{
try {
Marshal.GetHINSTANCE ((Module) null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("m", ex.ParamName, "#5");
}
}
#endif
[Test]
public void GetHRForException ()
{
Assert.AreEqual (0, Marshal.GetHRForException (null));
Assert.IsTrue (Marshal.GetHRForException (new Exception ()) < 0);
Assert.AreEqual (12345, Marshal.GetHRForException (new IOException ("test message", 12345)));
}
[Test] // bug #319009
public void StringToHGlobalUni ()
{
IntPtr handle = Marshal.StringToHGlobalUni ("unicode data");
string s = Marshal.PtrToStringUni (handle);
Assert.AreEqual (12, s.Length, "#1");
handle = Marshal.StringToHGlobalUni ("unicode data string");
s = Marshal.PtrToStringUni (handle);
Assert.AreEqual (19, s.Length, "#2");
}
[Test]
public void ReadIntByte ()
{
IntPtr ptr = Marshal.AllocHGlobal (4);
try {
Marshal.WriteByte (ptr, 0, 0x1);
Marshal.WriteByte (ptr, 1, 0x2);
Assert.AreEqual (0x1, Marshal.ReadByte (ptr));
Assert.AreEqual (0x1, Marshal.ReadByte (ptr, 0));
Assert.AreEqual (0x2, Marshal.ReadByte (ptr, 1));
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void ReadInt16 ()
{
IntPtr ptr = Marshal.AllocHGlobal (64);
try {
Marshal.WriteInt16 (ptr, 0, 0x1234);
Marshal.WriteInt16 (ptr, 2, 0x4567);
Marshal.WriteInt16 (ptr, 5, 0x4567);
Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr));
Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr, 0));
Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 2));
Assert.AreEqual (0x4567, Marshal.ReadInt16 ((ptr + 5)));
Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 5));
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void ReadInt32 ()
{
IntPtr ptr = Marshal.AllocHGlobal (64);
try {
Marshal.WriteInt32 (ptr, 0, 0x12345678);
Marshal.WriteInt32 (ptr, 4, 0x77654321);
Marshal.WriteInt32 (ptr, 10, 0x77654321);
Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr));
Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr, 0));
Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 4));
Assert.AreEqual (0x77654321, Marshal.ReadInt32 ((ptr + 10)));
Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 10));
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void ReadInt32_Endian ()
{
IntPtr ptr = Marshal.AllocHGlobal (4);
try {
Marshal.WriteByte (ptr, 0, 0x01);
Marshal.WriteByte (ptr, 1, 0x02);
Marshal.WriteByte (ptr, 2, 0x03);
Marshal.WriteByte (ptr, 3, 0x04);
// Marshal MUST use the native CPU data
if (BitConverter.IsLittleEndian){
Assert.AreEqual (0x04030201, Marshal.ReadInt32 (ptr), "ReadInt32");
} else {
Assert.AreEqual (0x01020304, Marshal.ReadInt32 (ptr), "ReadInt32");
}
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void ReadInt64 ()
{
IntPtr ptr = Marshal.AllocHGlobal (16);
try {
Marshal.WriteInt64 (ptr, 0, 0x12345678ABCDEFL);
Marshal.WriteInt64 (ptr, 8, 0x87654321ABCDEFL);
Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr));
Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr, 0));
Assert.AreEqual (0x87654321ABCDEFL, Marshal.ReadInt64 (ptr, 8));
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void BSTR_Roundtrip ()
{
string s = "mono";
IntPtr ptr = Marshal.StringToBSTR (s);
string s2 = Marshal.PtrToStringBSTR (ptr);
Assert.AreEqual (s, s2, "string");
}
[Test]
public void StringToBSTRWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToBSTR (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringBSTR (ptr);
Assert.AreEqual (128, s2.Length, "Length-2");
} finally {
Marshal.FreeBSTR (ptr);
}
}
[Test]
public void StringToHGlobalAnsiWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToHGlobalAnsi (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringAnsi (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void StringToHGlobalAutoWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToHGlobalAuto (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringAuto (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void StringToHGlobalUniWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToHGlobalUni (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringUni (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeHGlobal (ptr);
}
}
[Test]
public void StringToCoTaskMemAnsiWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToCoTaskMemAnsi (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringAnsi (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeCoTaskMem (ptr);
}
}
[Test]
public void StringToCoTaskMemAutoWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToCoTaskMemAuto (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringAuto (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeCoTaskMem (ptr);
}
}
[Test]
public void StringToCoTaskMemUniWithNullValues ()
{
int size = 128;
string s = String.Empty.PadLeft (size, '\0');
Assert.AreEqual (size, s.Length, "Length-1");
IntPtr ptr = Marshal.StringToCoTaskMemUni (s);
try {
for (int i = 0; i < size; i += 4)
Marshal.WriteInt32 (ptr, i, 0);
string s2 = Marshal.PtrToStringUni (ptr);
Assert.AreEqual (0, s2.Length, "Length-2");
} finally {
Marshal.FreeCoTaskMem (ptr);
}
}
private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
private static char[] PlainText = new char[] { 'a', 'b', 'c' };
private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
private unsafe SecureString GetSecureString ()
{
fixed (char* p = &PlainText[0]) {
return new SecureString (p, PlainText.Length);
}
}
[Test]
public void SecureStringToBSTR_Null ()
{
try {
Marshal.SecureStringToBSTR (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("s", ex.ParamName, "#5");
}
}
[Test]
public void SecureStringToBSTR ()
{
try {
SecureString ss = GetSecureString ();
IntPtr p = Marshal.SecureStringToBSTR (ss);
char[] decrypted = new char[ss.Length];
Marshal.Copy (p, decrypted, 0, decrypted.Length);
Assert.AreEqual (PlainText, decrypted, "Decrypted");
Marshal.ZeroFreeBSTR (p);
} catch (NotSupportedException) {
Assert.Ignore (NotSupported);
}
}
[Test]
public void SecureStringToCoTaskMemAnsi_Null ()
{
try {
Marshal.SecureStringToCoTaskMemAnsi (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("s", ex.ParamName, "#5");
}
}
[Test]
public void SecureStringToCoTaskMemAnsi ()
{
try {
SecureString ss = GetSecureString ();
IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
byte[] decrypted = new byte[ss.Length];
Marshal.Copy (p, decrypted, 0, decrypted.Length);
Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
Marshal.ZeroFreeCoTaskMemAnsi (p);
} catch (NotSupportedException) {
Assert.Ignore (NotSupported);
}
}
[Test]
public void SecureStringToCoTaskMemUnicode_Null ()
{
try {
Marshal.SecureStringToCoTaskMemUnicode (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("s", ex.ParamName, "#5");
}
}
[Test]
public void SecureStringToCoTaskMemUnicode ()
{
try {
SecureString ss = GetSecureString ();
IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
char[] decrypted = new char[ss.Length];
Marshal.Copy (p, decrypted, 0, decrypted.Length);
Assert.AreEqual (PlainText, decrypted, "Decrypted");
Marshal.ZeroFreeCoTaskMemUnicode (p);
} catch (NotSupportedException) {
Assert.Ignore (NotSupported);
}
}
[Test]
public void SecureStringToGlobalAllocAnsi_Null ()
{
try {
Marshal.SecureStringToGlobalAllocAnsi (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("s", ex.ParamName, "#5");
}
}
[Test]
public void SecureStringToGlobalAllocAnsi ()
{
try {
SecureString ss = GetSecureString ();
IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
byte[] decrypted = new byte[ss.Length];
Marshal.Copy (p, decrypted, 0, decrypted.Length);
Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
Marshal.ZeroFreeGlobalAllocAnsi (p);
} catch (NotSupportedException) {
Assert.Ignore (NotSupported);
}
}
[Test]
public void SecureStringToGlobalAllocUnicode_Null ()
{
try {
Marshal.SecureStringToGlobalAllocUnicode (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("s", ex.ParamName, "#5");
}
}
[Test]
public void SecureStringToGlobalAllocUnicode ()
{
try {
SecureString ss = GetSecureString ();
IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
char[] decrypted = new char[ss.Length];
Marshal.Copy (p, decrypted, 0, decrypted.Length);
Assert.AreEqual (PlainText, decrypted, "Decrypted");
Marshal.ZeroFreeGlobalAllocUnicode (p);
} catch (NotSupportedException) {
Assert.Ignore (NotSupported);
}
}
#if !MOBILE
[Test]
public void TestGetComSlotForMethodInfo ()
{
Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
for (int i = 0; i < 10; i++)
Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
}
[Test]
public void TestGetComSlotForMethod_Method_Null ()
{
try {
Marshal.GetComSlotForMethodInfo (null);
Assert.Fail ("#1");
} catch (ArgumentNullException ex) {
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("m", ex.ParamName, "#5");
}
}
[Test]
public void TestGetComSlotForMethodInfo_Method_NotOnInterface ()
{
MethodInfo m = typeof(TestCoClass).GetMethod ("DoNothing");
try {
Marshal.GetComSlotForMethodInfo (m);
Assert.Fail ("#1");
} catch (ArgumentException ex) {
// The MemberInfo must be an interface method
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual ("m", ex.ParamName, "#5");
}
}
#endif
[Test]
public void TestPtrToStringAuto ()
{
string input = Guid.NewGuid ().ToString ();
string output;
string output2;
int len = 4;
IntPtr ptr;
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
// Auto -> Uni
ptr = Marshal.StringToHGlobalAuto (input);
output = Marshal.PtrToStringUni (ptr);
output2 = Marshal.PtrToStringUni (ptr, len);
} else {
// Auto -> Ansi
ptr = Marshal.StringToHGlobalAuto (input);
output = Marshal.PtrToStringAnsi (ptr);
output2 = Marshal.PtrToStringAnsi (ptr, len);
}
try {
Assert.AreEqual (input, output, "#1");
Assert.AreEqual (input.Substring (0, len), output2, "#2");
} finally {
Marshal.FreeHGlobal (ptr);
}
}
#if !MOBILE
[Test]
public void TestGenerateProgIdForType()
{
string output;
output = Marshal.GenerateProgIdForType(typeof(TestCoClass));
Assert.AreEqual ("MonoTests.System.Runtime.InteropServices.TestCoClass", output, "#1");
output = Marshal.GenerateProgIdForType(typeof(TestCoClassWithProgId));
Assert.AreEqual ("CoClassWithProgId", output, "#2");
}
#endif
[Test]
public void TestGlobalAlloc ()
{
IntPtr mem = Marshal.AllocHGlobal (100);
mem = Marshal.ReAllocHGlobal (mem, (IntPtr) 1000000);
Marshal.FreeHGlobal (mem);
}
[Test]
public void FreeHGlobal ()
{
// clear user doubts on assistly #6749
for (int i = 0; i < 1024; i++) {
IntPtr p = Marshal.AllocHGlobal (1024 * 1024);
Assert.AreNotEqual (IntPtr.Zero, p, i.ToString ());
Marshal.FreeHGlobal (p);
}
}
[StructLayout (LayoutKind.Sequential)]
public struct SimpleStruct2 {
public int a;
public int b;
}
[Test]
public void PtrToStructureNull ()
{
Assert.IsNull (Marshal.PtrToStructure (IntPtr.Zero, typeof (SimpleStruct2)));
}
[Test]
public void TestGetExceptionForHR ()
{
const int E_OUTOFMEMORY = unchecked ((int) 0x8007000E);
const int E_INVALIDARG = unchecked ((int) 0X80070057);
Exception ex = Marshal.GetExceptionForHR (E_OUTOFMEMORY);
Assert.AreEqual (typeof (OutOfMemoryException), ex.GetType (), "E_OUTOFMEMORY");
ex = Marshal.GetExceptionForHR (E_INVALIDARG);
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
}
bool RunningOnMono {
get {
return (Type.GetType ("System.MonoType", false) != null);
}
}
#if !MOBILE
[DllImport ("kernel32.dll", SetLastError = true)]
[PreserveSig]
static extern uint GetModuleFileName (
[In]
IntPtr hModule,
[Out]
StringBuilder lpFilename,
[In]
[MarshalAs (UnmanagedType.U4)]
int nSize
);
#endif
#if !FULL_AOT_RUNTIME
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class FourByteStruct
{
public UInt16 value1;
public UInt16 value2;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class ByteArrayFourByteStruct : FourByteStruct
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
public byte[] array;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class SingleByteStruct
{
public byte value1;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class ByteArraySingleByteStruct : SingleByteStruct
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
public byte[] array1;
public byte value2;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public class ByteArraySingleByteChildStruct : ByteArraySingleByteStruct
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
public byte[] array2;
}
[Test]
public void CheckByteArrayFourByteStruct()
{
ByteArrayFourByteStruct myStruct = new ByteArrayFourByteStruct
{ value1 = 42, value2 = 53, array = Encoding.UTF8.GetBytes( "Hello" ) };
byte[] buffer = Serialize (myStruct);
UInt16 value1 = BitConverter.ToUInt16 (buffer, 0);
UInt16 value2 = BitConverter.ToUInt16 (buffer, 2);
string array = Encoding.UTF8.GetString (buffer, 4, 5);
Assert.AreEqual((UInt16)42, value1);
Assert.AreEqual((UInt16)53, value2);
Assert.AreEqual ("Hello", array);
}
[Test]
public void CheckByteArraySingleByteChildStruct()
{
ByteArraySingleByteChildStruct myStruct = new ByteArraySingleByteChildStruct
{ value1 = 42, array1 = Encoding.UTF8.GetBytes( "Hello" ), value2 = 53, array2 = Encoding.UTF8.GetBytes( "World" ) };
byte[] array = Serialize (myStruct);
byte value1 = array [0];
string array1 = Encoding.UTF8.GetString (array, 1, 5);
byte value2 = array [6];
string array2 = Encoding.UTF8.GetString (array, 7, 5);
Assert.AreEqual((byte)42, value1);
Assert.AreEqual ("Hello", array1);
Assert.AreEqual((byte)53, value2);
Assert.AreEqual ("World", array2);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct FiveByteStruct
{
public uint uIntField;
public byte byteField;
};
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Base
{
public ushort firstUShortField;
public ushort secondUShortField;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Derived : Base
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public FiveByteStruct[] arrayField;
}
[Test]
public void CheckPtrToStructureWithFixedArrayAndBaseClassFields()
{
const int arraySize = 6;
var derived = new Derived
{
arrayField = new FiveByteStruct[arraySize],
firstUShortField = 42,
secondUShortField = 43
};
for (var i = 0; i < arraySize; ++i)
{
derived.arrayField[i].byteField = (byte)i;
derived.arrayField[i].uIntField = (uint)i * 10;
}
var array = Serialize(derived);
var deserializedDerived = Deserialize<Derived>(array);
Assert.AreEqual(derived.firstUShortField, deserializedDerived.firstUShortField, "The firstUShortField differs, which is not expected.");
Assert.AreEqual(derived.secondUShortField, deserializedDerived.secondUShortField, "The secondUShortField differs, which is not expected.");
for (var i = 0; i < arraySize; ++i)
{
Assert.AreEqual(derived.arrayField[i].byteField, deserializedDerived.arrayField[i].byteField, string.Format("The byteField at index {0} differs, which is not expected.", i));
Assert.AreEqual(derived.arrayField[i].uIntField, deserializedDerived.arrayField[i].uIntField, string.Format("The uIntField at index {0} differs, which is not expected.", i));
}
}
public static byte[] Serialize( object obj )
{
int nTypeSize = Marshal.SizeOf( obj );
byte[] arrBuffer = new byte[nTypeSize];
GCHandle hGCHandle = GCHandle.Alloc( arrBuffer, GCHandleType.Pinned );
IntPtr pBuffer = hGCHandle.AddrOfPinnedObject();
Marshal.StructureToPtr( obj, pBuffer, false );
hGCHandle.Free();
return arrBuffer;
}
public static T Deserialize<T>(byte[] buffer)
{
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
var pBuffer = handle.AddrOfPinnedObject();
var objResult = (T)Marshal.PtrToStructure(pBuffer, typeof(T));
handle.Free();
return objResult;
}
#endif
}
#if !MOBILE
[ComImport()]
[Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
interface ITestDefault
{
void DoNothing ();
}
[ComImport()]
[Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
interface ITestDispatch
{
void DoNothing ();
}
[ComImport()]
[Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
interface ITestDual
{
void DoNothing ();
}
[ComImport()]
[Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ITestUnknown
{
void DoNothing ();
}
[ComImport()]
[Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
interface ITestInterface
{
void Method0 ();
void Method1 ();
void Method2 ();
void Method3 ();
void Method4 ();
void Method5 ();
void Method6 ();
void Method7 ();
void Method8 ();
void Method9 ();
}
public class TestCoClass : ITestDispatch
{
public void DoNothing ()
{
}
}
[ProgId("CoClassWithProgId")]
public class TestCoClassWithProgId : ITestDispatch
{
public void DoNothing ()
{
}
}
#endif
}