public unsafe static int Main () { BlittableStruct ss = new BlittableStruct (); int size = Marshal.SizeOf (typeof (BlittableStruct)); Console.WriteLine ("BlittableStruct:" + size); if (size != 8) return 1; IntPtr p = Marshal.AllocHGlobal (size); ss.a = 123; ss.b = 124; Marshal.StructureToPtr (ss, p, false); Type t = ss.GetType (); if (Marshal.ReadInt32 (p, 0) != 123) return 1; if (Marshal.ReadInt32 (p, 4) != 124) return 1; BlittableStruct cp = (BlittableStruct)Marshal.PtrToStructure (p, ss.GetType ()); if (cp.a != 123) return 2; if (cp.b != 124) return 2; return 0; }
unsafe static void Main(string[] args) { // 컴파일 가능 { BlittableStruct inst = new BlittableStruct(); BlittableStruct *pInst = &inst; } // BlittableStruct와 동일한 메모리 구조임에도 C# 7.3 이전에는 컴파일 오류 { BlittableGenericStruct <byte> inst = new BlittableGenericStruct <byte>(); BlittableGenericStruct <byte> *pInst = &inst; } Nested <byte> inst1 = new Nested <byte>(); // BlittableGenericStruct<byte> 타입 자체가 unmanaged 조건을 만족하지만 // C# 7.3 이전에는 컴파일 오류 Nested <BlittableGenericStruct <byte> > inst2 = new Nested <BlittableGenericStruct <byte> >(); // C# 7.3 이전에는 컴파일 오류 CallUnmanaged(new BlittableGenericStruct <byte>()); // 아래의 코드는 아무리 실행해도 GC가 발생하지 않는다. // while (true) { using (NativeMemory <int> buf = new NativeMemory <int>(1024)) { Span <int> viewBuf = buf.GetView(); for (int i = 0; i < viewBuf.Length; i++) { viewBuf[i] = i; } } using (NativeMemory <byte> buf = new NativeMemory <byte>(1024)) { Span <byte> viewBuf = buf.GetView(); for (int i = 0; i < viewBuf.Length; i++) { viewBuf[i] = (byte)i; } } } }
public void StructTest() { BlittableStruct dat = new BlittableStruct() { ValOne = int.MaxValue, ValTwo = 123, ValThree = 321 }; int length = 16; for (int i = 0; i < 4 * length; i += length) { BinaryHelper.Write(m_buffer, i, dat); } for (int i = 0; i < 4 * length; i += length) { var other = BinaryHelper.Read <BlittableStruct>(m_buffer, i); Assert.True(other.IsEqual(dat)); } }
public unsafe static int Main() { BlittableStruct ss = new BlittableStruct(); int size = Marshal.SizeOf(typeof(BlittableStruct)); Console.WriteLine("BlittableStruct:" + size); if (size != 8) { return(1); } IntPtr p = Marshal.AllocHGlobal(size); ss.a = 123; ss.b = 124; Marshal.StructureToPtr(ss, p, false); Type t = ss.GetType(); if (Marshal.ReadInt32(p, 0) != 123) { return(1); } if (Marshal.ReadInt32(p, 4) != 124) { return(1); } BlittableStruct cp = (BlittableStruct)Marshal.PtrToStructure(p, ss.GetType()); if (cp.a != 123) { return(2); } if (cp.b != 124) { return(2); } return(0); }
static void TestBlittableStruct() { Console.WriteLine("TestBlittableStruct"); BlittableStruct blittableStruct = new BlittableStruct(); blittableStruct.a = 200; blittableStruct.b = 300; blittableStruct.c = 10; blittableStruct.d = 123; blittableStruct.p = new IntPtr(100); object boxedBlittableStruct = (object)blittableStruct; int offsetOfB = Marshal.OffsetOf <BlittableStruct>("b").ToInt32(); int offsetOfC = Marshal.OffsetOf <BlittableStruct>("c").ToInt32(); int offsetOfD = Marshal.OffsetOf <BlittableStruct>("d").ToInt32(); int offsetOfP = Marshal.OffsetOf <BlittableStruct>("p").ToInt32(); Assert.AreEqual(Marshal.ReadInt32(boxedBlittableStruct, 0), 200); Assert.AreEqual(Marshal.ReadInt32(boxedBlittableStruct, offsetOfB), 300); Assert.AreEqual(Marshal.ReadByte(boxedBlittableStruct, offsetOfC), 10); Assert.AreEqual(Marshal.ReadInt16(boxedBlittableStruct, offsetOfD), 123); Assert.AreEqual(Marshal.ReadIntPtr(boxedBlittableStruct, offsetOfP), new IntPtr(100)); Marshal.WriteInt32(boxedBlittableStruct, 0, 300); Marshal.WriteInt32(boxedBlittableStruct, offsetOfB, 400); Marshal.WriteByte(boxedBlittableStruct, offsetOfC, 20); Marshal.WriteInt16(boxedBlittableStruct, offsetOfD, 144); Marshal.WriteIntPtr(boxedBlittableStruct, offsetOfP, new IntPtr(500)); Assert.AreEqual(((BlittableStruct)boxedBlittableStruct).a, 300); Assert.AreEqual(((BlittableStruct)boxedBlittableStruct).b, 400); Assert.AreEqual(((BlittableStruct)boxedBlittableStruct).c, 20); Assert.AreEqual(((BlittableStruct)boxedBlittableStruct).d, 144); Assert.AreEqual(((BlittableStruct)boxedBlittableStruct).p, new IntPtr(500)); }
public void CouldSerializeBlittableStructArray() { var bytes = new byte[1000]; var arr = new BlittableStruct[2]; arr[0] = new BlittableStruct { Value1 = 123, Value2 = 1230 }; arr[1] = new BlittableStruct { Value1 = 456, Value2 = 4560 }; var len = BinarySerializer.Write(arr, bytes); Assert.AreEqual(8 + 12 * 2, len); BlittableStruct[] arr2 = null; var len2 = BinarySerializer.Read(bytes, ref arr2); Assert.AreEqual(len, len2); Assert.IsTrue(arr.SequenceEqual(arr2)); }
public static BlittableStruct delegate_test_blittable_struct (BlittableStruct ss) { BlittableStruct res; res.a = -ss.a; res.b = -ss.b; res.c = -ss.c; res.d = -ss.d; return res; }
private static void TestMarshalStructAPIs() { Console.WriteLine("Testing Marshal APIs for structs"); BlittableStruct bs = new BlittableStruct() { FirstField = 1.0f, SecondField = 2.0f, ThirdField = 3 }; int bs_size = Marshal.SizeOf <BlittableStruct>(bs); ThrowIfNotEquals(40, bs_size, "Marshal.SizeOf<BlittableStruct> failed"); IntPtr bs_memory = Marshal.AllocHGlobal(bs_size); try { Marshal.StructureToPtr <BlittableStruct>(bs, bs_memory, false); BlittableStruct bs2 = Marshal.PtrToStructure <BlittableStruct>(bs_memory); ThrowIfNotEquals(true, bs2.FirstField == 1.0f && bs2.SecondField == 2.0f && bs2.ThirdField == 3, "BlittableStruct marshalling Marshal API failed"); IntPtr offset = Marshal.OffsetOf <BlittableStruct>("SecondField"); ThrowIfNotEquals(new IntPtr(12), offset, "Struct marshalling OffsetOf failed."); } finally { Marshal.FreeHGlobal(bs_memory); } NonBlittableStruct ts = new NonBlittableStruct() { f1 = 100, f2 = true, f3 = false, f4 = true }; int size = Marshal.SizeOf <NonBlittableStruct>(ts); ThrowIfNotEquals(16, size, "Marshal.SizeOf<NonBlittableStruct> failed"); IntPtr memory = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr <NonBlittableStruct>(ts, memory, false); NonBlittableStruct ts2 = Marshal.PtrToStructure <NonBlittableStruct>(memory); ThrowIfNotEquals(true, ts2.f1 == 100 && ts2.f2 == true && ts2.f3 == false && ts2.f4 == true, "NonBlittableStruct marshalling Marshal API failed"); IntPtr offset = Marshal.OffsetOf <NonBlittableStruct>("f2"); ThrowIfNotEquals(new IntPtr(4), offset, "Struct marshalling OffsetOf failed."); } finally { Marshal.FreeHGlobal(memory); } BlittableClass bc = new BlittableClass() { f1 = 100, f2 = 12345678, f3 = 999, f4 = -4 }; int bc_size = Marshal.SizeOf <BlittableClass>(bc); ThrowIfNotEquals(24, bc_size, "Marshal.SizeOf<BlittableClass> failed"); IntPtr bc_memory = Marshal.AllocHGlobal(bc_size); try { Marshal.StructureToPtr <BlittableClass>(bc, bc_memory, false); BlittableClass bc2 = Marshal.PtrToStructure <BlittableClass>(bc_memory); ThrowIfNotEquals(true, bc2.f1 == 100 && bc2.f2 == 12345678 && bc2.f3 == 999 && bc2.f4 == -4, "BlittableClass marshalling Marshal API failed"); } finally { Marshal.FreeHGlobal(bc_memory); } NonBlittableClass nbc = new NonBlittableClass() { f1 = false, f2 = true, f3 = 42 }; int nbc_size = Marshal.SizeOf <NonBlittableClass>(nbc); ThrowIfNotEquals(12, nbc_size, "Marshal.SizeOf<NonBlittableClass> failed"); IntPtr nbc_memory = Marshal.AllocHGlobal(nbc_size); try { Marshal.StructureToPtr <NonBlittableClass>(nbc, nbc_memory, false); NonBlittableClass nbc2 = Marshal.PtrToStructure <NonBlittableClass>(nbc_memory); ThrowIfNotEquals(true, nbc2.f1 == false && nbc2.f2 == true && nbc2.f3 == 42, "NonBlittableClass marshalling Marshal API failed"); } finally { Marshal.FreeHGlobal(nbc_memory); } }
static void Main(string[] args) { var unitTest = new ConversionUnitTest(); { string title = "Primitives"; bool x = false; int refx = 98; PrintSend(title, x, refx); var ret = unitTest.Primitives(x, out char outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "Strings"; var x = "Hello C++"; var refx = "Have A String"; PrintSend(title, x, refx); var ret = unitTest.Strings(x, out string outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "SimpleStructs"; var x = new BlittableStruct(1, 3, 3, 7); var refx = new BlittableStruct(8, 8, 8, 8); PrintSend(title, x, refx); var ret = unitTest.SimpleStructs(x, out BlittableStruct outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "Objects"; var x = new DummyClass() { Nugget = "DummyC#In" }; var refx = new DummyClass() { Nugget = "DummyC#Ref" }; PrintSend(title, x, refx); var ret = unitTest.Objects(x, out DummyClass outx, ref refx); PrintRecv(title, outx, refx, ret); refx.Dispose(); x.Dispose(); } { string title = "NamedDelegates"; NamedDelegate x = (a, b) => a.Length + b.Length; NamedDelegate refx = (a, b) => (int)a[0] * (int)b[0]; PrintSend(title, x, refx); var ret = unitTest.NamedDelegates(x, out NamedDelegate outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "ComplexStructs"; var x = new ComplexStruct("ComplexC#In", new BlittableStruct(5, 4, 6, 3), new DummyClass() { Nugget = "WelcomeNugget" }, (u, v) => u | v); var refx = new ComplexStruct("ComplexC#Ref", new BlittableStruct(9, 0, 0, 9), new DummyClass() { Nugget = "RefNugget" }, (u, v) => u * u * v); PrintSend(title, x, refx); var ret = unitTest.ComplexStructs(x, out ComplexStruct outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "PrimitiveArrays"; var x = new bool[] { true, false, false, true, false, true }; var refx = new int[] { 10, 100, 1000, 10000 }; PrintSend(title, x, refx); var ret = unitTest.PrimitiveArrays(x, out char[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "StringArrays"; var x = new string[] { "The", "Quick", "Brown", "Fox" }; var refx = new string[] { "Some", "Strings" }; PrintSend(title, x, refx); var ret = unitTest.StringArrays(x, out string[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "SimpleStructArrays"; var x = new BlittableStruct[] { new BlittableStruct(1001, 1002, 1003, 1004), new BlittableStruct(2001, 2002, 2003, 2004), new BlittableStruct(3001, 3002, 3003, 3004) }; var refx = new BlittableStruct[] { new BlittableStruct(-1, -2, -3, -4), new BlittableStruct(-5, -6, -7, -8) }; PrintSend(title, x, refx); var ret = unitTest.SimpleStructArrays(x, out BlittableStruct[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "ComplexStructArrays"; var x = new ComplexStruct[] { new ComplexStruct("ComplexArrC#[0]", new BlittableStruct(-1, 0, 1, 0), new DummyClass() { Nugget = "ComplexArrNugget[0]" }, (a, b) => a * a * b * b), new ComplexStruct("ComplexArrC#[1]", new BlittableStruct(4, 3, 2, 1), new DummyClass() { Nugget = "ComplexArrNugget[1]" }, (a, b) => b * b - a * a) }; var refx = new ComplexStruct[] { new ComplexStruct("ComplexArrRefC#[0]", new BlittableStruct(11, 12, 13, 14), new DummyClass() { Nugget = "ComplexArrRefNugget[0]" }, (a, b) => a - b) }; PrintSend(title, x, refx); var ret = unitTest.ComplexStructArrays(x, out ComplexStruct[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "ObjectArrays"; var x = new DummyClass[] { new DummyClass() { Nugget = "Arr0" }, new DummyClass() { Nugget = "Arr1" }, null, new DummyClass() { Nugget = "Arr3" } }; var refx = new DummyClass[] { null, null }; PrintSend(title, x, refx); var ret = unitTest.ObjectArrays(x, out DummyClass[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { string title = "NamedDelegateArrays"; var x = new NamedDelegate[] { (a, b) => a.Length * b.Length, (a, b) => a.Length + (int)b[0], }; var refx = new NamedDelegate[] { (a, b) => (int)a[0] * (int)b[0] }; PrintSend(title, x, refx); var ret = unitTest.NamedDelegateArrays(x, out NamedDelegate[] outx, ref refx); PrintRecv(title, outx, refx, ret); } { try { Func <char[], string> refx = null; //unitTest.GenericDelegates(null, out var outx, ref refx); } catch (Exception e) { Console.WriteLine("Caught Exception : " + e.GetType().Name); } } var test = new ITestClass(); Console.WriteLine(string.Format("RO Property = {0}", test.ReadOnlyProperty)); Console.WriteLine(string.Format("Property = {0}", test.Property)); test.Property = 17; Console.WriteLine(string.Format("Property = {0}", test.Property)); try { Console.WriteLine("Testing AccessDeniedException..."); unitTest.ExCheckAccessDenied(); Console.WriteLine("Error: No Exception Thrown!"); } catch (AccessViolationException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } try { Console.WriteLine("Testing ArgumentException..."); unitTest.ExCheckArgument(); Console.WriteLine("Error: No Exception Thrown!"); } catch (ArgumentException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } try { Console.WriteLine("Testing ArgumentNullException..."); unitTest.ExCheckArgumentNull(); Console.WriteLine("Error: No Exception Thrown!"); } catch (ArgumentNullException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } try { Console.WriteLine("Testing Generic Exceptions..."); unitTest.ExCheckGeneric(); Console.WriteLine("Error: No Exception Thrown!"); } catch (Exception e) { Console.WriteLine(e.Message); } try { Console.WriteLine("Testing Generic STD Exceptions..."); unitTest.ExCheckGenericStd(); Console.WriteLine("Error: No Exception Thrown!"); } catch (Exception e) { Console.WriteLine(e.Message); } try { Console.WriteLine("Testing InvalidOperationException..."); unitTest.ExCheckInvalidOperation(); Console.WriteLine("Error: No Exception Thrown!"); } catch (InvalidOperationException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } try { Console.WriteLine("Testing NotImplementedException..."); unitTest.ExCheckNotImplemented(); Console.WriteLine("Error: No Exception Thrown!"); } catch (NotImplementedException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } try { Console.WriteLine("Testing NullReferenceException..."); unitTest.ExCheckNullReference(); Console.WriteLine("Error: No Exception Thrown!"); } catch (NullReferenceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine("ERROR: Improper exception: "); Console.WriteLine(e.ToString()); } }