static int pass_struct_spill(TestStruct2 regStruct) { int retVal; retVal = receive_struct_spill(1, 2, 3, 4, 5, regStruct); return(retVal); }
public void Serialize_WithTestStruct2_CanBeReadByOracle() { const int outerIntProp = 102; const int intProp = 42; const byte byteProp = 22; const short shortProp = 62; var serializer = new FlatBuffersSerializer(); var obj = new TestStruct1() { IntProp = intProp, ByteProp = byteProp, ShortProp = shortProp }; var root = new TestStruct2() { IntProp = outerIntProp, TestStructProp = obj }; var buffer = new byte[32]; serializer.Serialize(root, buffer, 0, buffer.Length); var oracle = new SerializationTestOracle(); var oracleResult = oracle.ReadTestStruct2(buffer); Assert.AreEqual(root.IntProp, oracleResult.IntProp); Assert.AreEqual(root.TestStructProp.IntProp, oracleResult.TestStructProp.IntProp); Assert.AreEqual(root.TestStructProp.ByteProp, oracleResult.TestStructProp.ByteProp); Assert.AreEqual(root.TestStructProp.ShortProp, oracleResult.TestStructProp.ShortProp); }
static int pass_spill_struct_spill(int a, int b, int c, int d, int e, TestStruct2 regStruct) { int retVal; retVal = receive_struct_spill(a, b, c, d, e, regStruct); return(retVal); }
public void StructWithReferenceToUnsealedType() { var x = new TestStruct2 { Ref = new TestC() }; RoundTrip(x, (original, loaded) => original.Ref.Value == loaded.Ref.Value); }
public void Sr_ReadLeInt32_Field() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 }, 0); var test = new TestStruct2(); var sr = new StructureReader(test); sr.Read(rdr); Assert.AreEqual((int) 0x12345678, test.lField); }
public void Sr_ReadLeInt32_Field() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 }, 0); var test = new TestStruct2(); var sr = new StructureReader(test); sr.Read(rdr); Assert.AreEqual((int)0x12345678, test.lField); }
static int receive_struct_spill(int a, int b, int c, int d, int e, TestStruct2 regStruct) { if (regStruct.b == 181) { return(0); } else { return(10); } }
public void StructWithReferenceToDerivedType() { var x = new TestStruct2 { Ref = new TestD { Value = 13 } }; RoundTrip(x, (original, loaded) => original.Ref.Value == loaded.Ref.Value && ((TestD)loaded.Ref).Value == 13); }
static int receive_spill_struct(TestStruct2 regStruct) { if (regStruct.b == 181) { return(0); } else { return(8); } }
public void ReadIntIntIntStructLittleEndianGeneric() { // Will test the fast path byte[] data = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }; MessageReader reader = new MessageReader(EndianFlag.Little, data); TestStruct2 stct = reader.ReadStruct <TestStruct2> (); Assert.AreEqual(1, stct.Item1); Assert.AreEqual(2, stct.Item2); Assert.AreEqual(3, stct.Item3); }
public void TestMapping() { var s1 = new TestStruct(); AssertSuccessRestored(s1); var s2 = new TestStruct2(); AssertSuccessRestored(s2); s2.Items.Add(new TestStruct()); AssertSuccessRestored(s2); s2.Items[0].a = 1; AssertSuccessRestored(s2); s2.Items[0].c = "a"; AssertSuccessRestored(s2); }
public void CloneDel_Override_Struct() { int methodCalled = 0; CloneConfig <TestStruct2> .CloneDel = (x, y) => { methodCalled++; return(x); }; var source = new TestStruct2(6); var dest = source.GetClone(); Assert.Equal(source.Prop, dest.Prop); Assert.Equal(6, dest.Prop); Assert.Equal(1, methodCalled); }
public TestStruct2 ReadTestStruct2(byte[] buffer) { var test = new SerializationTests.TestStruct2(); var bb = new ByteBuffer(buffer); test.__init(0, bb); var result = new TestStruct2() { IntProp = test.IntProp, TestStructProp = new TestStruct1() { IntProp = test.TestStruct1Prop.IntProp, ByteProp = test.TestStruct1Prop.ByteProp, ShortProp = test.TestStruct1Prop.ShortProp } }; return(result); }
public bool PosTest3() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest3: Equals should return false when comparing with instance of different classes"); try { TestEmptyClass classInstance1 = new TestEmptyClass(); TestClass classInstance2 = new TestClass(); RuntimeTypeHandle classInstanceHandle1 = classInstance1.GetType().TypeHandle; RuntimeTypeHandle classInstanceHandle2 = classInstance2.GetType().TypeHandle; if (classInstanceHandle1.Equals(classInstanceHandle2)) { TestLibrary.TestFramework.LogError("003.1", "Equals returns true when comparing with instance of different classe"); retVal = false; } TestStruct1 ts1 = new TestStruct1(); TestStruct2 ts2 = new TestStruct2(); RuntimeTypeHandle structHandle1 = ts1.GetType().TypeHandle; RuntimeTypeHandle structHandle2 = ts2.GetType().TypeHandle; if (structHandle1.Equals(structHandle2)) { TestLibrary.TestFramework.LogError("003.2", "Equals returns false when comparing with instance of different structs"); retVal = false; } TestEnum1 te1 = TestEnum1.DEFAULT; TestEnum2 te2 = TestEnum2.DEFAULT; RuntimeTypeHandle enumHandle1 = te1.GetType().TypeHandle; RuntimeTypeHandle enumHandle2 = te2.GetType().TypeHandle; if (enumHandle1.Equals(enumHandle2)) { TestLibrary.TestFramework.LogError("003.3", "Equals returns false when comparing with instance of different enums"); retVal = false; } if (classInstanceHandle1.Equals(structHandle1)) { TestLibrary.TestFramework.LogError("003.4", "Equals returns false when comparing a instance of struct with a instance of class"); retVal = false; } if (classInstanceHandle1.Equals(enumHandle1)) { TestLibrary.TestFramework.LogError("003.5", "Equals returns false when comparing a instance of enum with a instance of class"); retVal = false; } if (structHandle1.Equals(enumHandle1)) { TestLibrary.TestFramework.LogError("003.6", "Equals returns false when comparing a instance of struct with a instance of enum"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("003.7", "Unexpected exception: " + e); TestLibrary.TestFramework.LogInformation(e.StackTrace); retVal = false; } return retVal; }
static int reg_struct_ret(TestStruct2 regStruct) { return regStruct.b; }
static TestStruct2 struct_ret(TestStruct2 regStruct) { regStruct.a = -1; regStruct.b = 72; return (regStruct); }
static int pass_spill_struct_spill(int a, int b, int c, int d, int e, TestStruct2 regStruct) { int retVal; retVal = receive_struct_spill(a, b, c, d, e, regStruct); return retVal; }
static int pass_struct_spill(TestStruct2 regStruct) { int retVal; retVal = receive_struct_spill(1, 2, 3, 4, 5, regStruct); return retVal; }
static int receive_struct_spill(int a, int b, int c, int d, int e, TestStruct2 regStruct) { if (regStruct.b == 181) return 0; else return 10; }
static int receive_spill_struct(TestStruct2 regStruct) { if (regStruct.b == 181) return 0; else return 8; }
public bool PosTest3() { bool retVal = true; TestLibrary.TestFramework.BeginScenario("PosTest3: Equals should return false when comparing with instance of different classes"); try { TestEmptyClass classInstance1 = new TestEmptyClass(); TestClass classInstance2 = new TestClass(); RuntimeTypeHandle classInstanceHandle1 = classInstance1.GetType().TypeHandle; RuntimeTypeHandle classInstanceHandle2 = classInstance2.GetType().TypeHandle; if (classInstanceHandle1.Equals(classInstanceHandle2)) { TestLibrary.TestFramework.LogError("003.1", "Equals returns true when comparing with instance of different classe"); retVal = false; } TestStruct1 ts1 = new TestStruct1(); TestStruct2 ts2 = new TestStruct2(); RuntimeTypeHandle structHandle1 = ts1.GetType().TypeHandle; RuntimeTypeHandle structHandle2 = ts2.GetType().TypeHandle; if (structHandle1.Equals(structHandle2)) { TestLibrary.TestFramework.LogError("003.2", "Equals returns false when comparing with instance of different structs"); retVal = false; } TestEnum1 te1 = TestEnum1.DEFAULT; TestEnum2 te2 = TestEnum2.DEFAULT; RuntimeTypeHandle enumHandle1 = te1.GetType().TypeHandle; RuntimeTypeHandle enumHandle2 = te2.GetType().TypeHandle; if (enumHandle1.Equals(enumHandle2)) { TestLibrary.TestFramework.LogError("003.3", "Equals returns false when comparing with instance of different enums"); retVal = false; } if (classInstanceHandle1.Equals(structHandle1)) { TestLibrary.TestFramework.LogError("003.4", "Equals returns false when comparing a instance of struct with a instance of class"); retVal = false; } if (classInstanceHandle1.Equals(enumHandle1)) { TestLibrary.TestFramework.LogError("003.5", "Equals returns false when comparing a instance of enum with a instance of class"); retVal = false; } if (structHandle1.Equals(enumHandle1)) { TestLibrary.TestFramework.LogError("003.6", "Equals returns false when comparing a instance of struct with a instance of enum"); retVal = false; } } catch (Exception e) { TestLibrary.TestFramework.LogError("003.7", "Unexpected exception: " + e); TestLibrary.TestFramework.LogInformation(e.StackTrace); retVal = false; } return(retVal); }
//ignore for now public void testEnumInStruct2() { var tmp = new TestStruct2(MyFlagsEnum.V2); }
public unsafe static int Main() { /// /// Testing simple struct size /// if (Marshal.SizeOf(typeof(TestStruct1)) != 32) { return(1); } TestStruct1 myStruct = new TestStruct1(); myStruct.a = 0x12345678; IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct1))); Marshal.StructureToPtr(myStruct, p, false); Type testType = typeof(TestStruct1); if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType, "a")) != myStruct.a) { return(2); } Marshal.FreeHGlobal(p); /// /// Testing struct size with ByValTStr string /// if (Marshal.SizeOf(typeof(TestStruct2)) != 32) { return(3); } TestStruct2 myStruct2 = new TestStruct2(); myStruct2.b = 0x12345678; p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct2))); Marshal.StructureToPtr(myStruct2, p, false); Type testType2 = typeof(TestStruct2); if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType2, "b")) != myStruct2.b) { return(4); } Marshal.FreeHGlobal(p); /// /// Test structure size and struct with inheritance /// if (Marshal.SizeOf(typeof(TestStruct3)) != 64) { return(5); } TestStruct3 myStruct3 = new TestStruct3(); myStruct3.b = 0x12345678; myStruct3.c = 0x76543210; p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct3))); Marshal.StructureToPtr(myStruct3, p, false); Type testType3 = typeof(TestStruct3); if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "b")) != myStruct3.b) { return(6); } if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "c")) != myStruct3.c) { return(7); } Marshal.FreeHGlobal(p); /// /// Also make sure OffsetOf returns the correct Exception. /// try { Marshal.OffsetOf(testType3, "blah"); return(8); } catch (ArgumentException e) { /// Way to go :) } catch (Exception e) { return(9); } // test size of structs with objects if (Marshal.SizeOf(typeof(TestStruct4)) != IntPtr.Size) { return(10); } if (Marshal.SizeOf(typeof(TestStruct5)) != IntPtr.Size) { return(11); } if (Marshal.SizeOf(typeof(TestStruct6)) != IntPtr.Size) { return(12); } // a VARIANT is if (Marshal.SizeOf(typeof(TestStruct7)) != 16) { return(13); } if (IsOSX() && IntPtr.Size == 4) { if (Marshal.SizeOf(typeof(TestStruct8)) != 12) { return(14); } if (Marshal.SizeOf(typeof(TestStruct10)) != 12) { return(16); } } else { if (Marshal.SizeOf(typeof(TestStruct8)) != 16 && Marshal.SizeOf(typeof(TestStruct8)) != 12) { return(14); } if (Marshal.SizeOf(typeof(TestStruct10)) != 16 && Marshal.SizeOf(typeof(TestStruct10)) != 12) { return(16); } } if (Marshal.SizeOf(typeof(TestStruct9)) != 12) { return(15); } if (Marshal.SizeOf(typeof(TestStruct11)) != 11) { return(17); } if (Marshal.SizeOf(typeof(TestStruct12)) != 6) { return(18); } if (Marshal.SizeOf(typeof(TestStruct13)) != 12) { return(19); } if (Marshal.SizeOf(typeof(TestStruct14)) != 12) { return(20); } return(0); }
public void StructWithNullReferenceToUnsealedType() { var x = new TestStruct2(); RoundTrip(x); }
public unsafe static int Main () { /// /// Testing simple struct size /// if(Marshal.SizeOf(typeof(TestStruct1)) != 32) { return 1; } TestStruct1 myStruct = new TestStruct1(); myStruct.a = 0x12345678; IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct1))); Marshal.StructureToPtr(myStruct, p, false); Type testType = typeof(TestStruct1); if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType, "a")) != myStruct.a) return 2; Marshal.FreeHGlobal(p); /// /// Testing struct size with ByValTStr string /// if(Marshal.SizeOf(typeof(TestStruct2)) != 32) return 3; TestStruct2 myStruct2 = new TestStruct2(); myStruct2.b = 0x12345678; p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct2))); Marshal.StructureToPtr(myStruct2, p, false); Type testType2 = typeof(TestStruct2); if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType2, "b")) != myStruct2.b) return 4; Marshal.FreeHGlobal(p); /// /// Test structure size and struct with inheritance /// if(Marshal.SizeOf(typeof(TestStruct3)) != 64) return 5; TestStruct3 myStruct3 = new TestStruct3(); myStruct3.b = 0x12345678; myStruct3.c = 0x76543210; p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TestStruct3))); Marshal.StructureToPtr(myStruct3, p, false); Type testType3 = typeof(TestStruct3); if(Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "b")) != myStruct3.b) return 6; if (Marshal.ReadInt32(p, (int)Marshal.OffsetOf(testType3, "c")) != myStruct3.c) return 7; Marshal.FreeHGlobal(p); /// /// Also make sure OffsetOf returns the correct Exception. /// try { Marshal.OffsetOf(testType3, "blah"); return 8; } catch(ArgumentException e) { /// Way to go :) } catch(Exception e) { return 9; } // test size of structs with objects if (Marshal.SizeOf (typeof (TestStruct4)) != IntPtr.Size) return 10; if (Marshal.SizeOf (typeof (TestStruct5)) != IntPtr.Size) return 11; if (Marshal.SizeOf (typeof (TestStruct6)) != IntPtr.Size) return 12; // a VARIANT is if (Marshal.SizeOf (typeof (TestStruct7)) != 16) return 13; if (IsOSX () && IntPtr.Size == 4) { if (Marshal.SizeOf (typeof (TestStruct8)) != 12) return 14; if (Marshal.SizeOf (typeof (TestStruct10)) != 12) return 16; } else { if (Marshal.SizeOf (typeof (TestStruct8)) != 16) return 14; if (Marshal.SizeOf (typeof (TestStruct10)) != 16) return 16; } if (Marshal.SizeOf (typeof (TestStruct9)) != 12) return 15; if (Marshal.SizeOf (typeof (TestStruct11)) != 11) return 17; if (Marshal.SizeOf (typeof (TestStruct12)) != 6) return 18; if (Marshal.SizeOf (typeof (TestStruct13)) != 12) return 19; if (Marshal.SizeOf (typeof (TestStruct14)) != 12) return 20; return 0; }
private static void TestStruct() { #if !CODEGEN_CPP Console.WriteLine("Testing Structs"); SequentialStruct ss = new SequentialStruct(); ss.f0 = 100; ss.f1 = 1; ss.f2 = 10.0f; ss.f3 = "Hello"; ThrowIfNotEquals(true, StructTest(ss), "Struct marshalling scenario1 failed."); StructTest_ByRef(ref ss); ThrowIfNotEquals(true, ss.f1 == 2 && ss.f2 == 11.0 && ss.f3.Equals("Ifmmp"), "Struct marshalling scenario2 failed."); SequentialStruct ss2 = new SequentialStruct(); StructTest_ByOut(out ss2); ThrowIfNotEquals(true, ss2.f0 == 1 && ss2.f1 == 1.0 && ss2.f2 == 1.0 && ss2.f3.Equals("0123456"), "Struct marshalling scenario3 failed."); NesterOfSequentialStruct.SequentialStruct ss3 = new NesterOfSequentialStruct.SequentialStruct(); ss3.f1 = 10.0f; ss3.f2 = 123; ThrowIfNotEquals(true, StructTest_Sequential2(ss3), "Struct marshalling scenario1 failed."); ExplicitStruct es = new ExplicitStruct(); es.f1 = 100; es.f2 = 100.0f; es.f3 = "Hello"; ThrowIfNotEquals(true, StructTest_Explicit(es), "Struct marshalling scenario4 failed."); NestedStruct ns = new NestedStruct(); ns.f1 = 100; ns.f2 = es; ThrowIfNotEquals(true, StructTest_Nested(ns), "Struct marshalling scenario5 failed."); SequentialStruct[] ssa = null; ThrowIfNotEquals(true, IsNULL(ssa), "Non-blittable array null check failed"); ssa = new SequentialStruct[3]; for (int i = 0; i < 3; i++) { ssa[i].f1 = 0; ssa[i].f1 = i; ssa[i].f2 = i * i; ssa[i].f3 = i.LowLevelToString(); } ThrowIfNotEquals(true, StructTest_Array(ssa, ssa.Length), "Array of struct marshalling failed"); InlineString ils = new InlineString(); InlineStringTest(ref ils); ThrowIfNotEquals("Hello World!", ils.name, "Inline string marshalling failed"); InlineArrayStruct ias = new InlineArrayStruct(); ias.inlineArray = new short[128]; for (short i = 0; i < 128; i++) { ias.inlineArray[i] = i; } ias.inlineString = "Hello"; InlineUnicodeStruct ius = new InlineUnicodeStruct(); ius.inlineString = "Hello World"; TestStruct2 ts = new TestStruct2() { f1 = 100, f2 = true }; int size = Marshal.SizeOf <TestStruct2>(ts); IntPtr memory = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr <TestStruct2>(ts, memory, false); TestStruct2 ts2 = Marshal.PtrToStructure <TestStruct2>(memory); ThrowIfNotEquals(true, ts2.f1 == 100 && ts2.f2 == true, "Struct marshalling Marshal API failed"); IntPtr offset = Marshal.OffsetOf <TestStruct2>("f2"); ThrowIfNotEquals(new IntPtr(8), offset, "Struct marshalling OffsetOf failed."); } finally { Marshal.FreeHGlobal(memory); } ThrowIfNotEquals(true, InlineArrayTest(ref ias, ref ius), "inline array marshalling failed"); bool pass = true; for (short i = 0; i < 128; i++) { if (ias.inlineArray[i] != i + 1) { pass = false; } } ThrowIfNotEquals(true, pass, "inline array marshalling failed"); ThrowIfNotEquals("Hello World", ias.inlineString, "Inline ByValTStr Ansi marshalling failed"); ThrowIfNotEquals("Hello World", ius.inlineString, "Inline ByValTStr Unicode marshalling failed"); // RhpThrowEx is not implemented in CPPCodeGen pass = false; AutoStruct autoStruct = new AutoStruct(); try { // passing struct with Auto layout should throw exception. StructTest_Auto(autoStruct); } catch (Exception) { pass = true; } ThrowIfNotEquals(true, pass, "Struct marshalling scenario6 failed."); Callbacks callbacks = new Callbacks(); callbacks.callback0 = new Callback0(callbackFunc0); callbacks.callback1 = new Callback1(callbackFunc1); callbacks.callback2 = new Callback2(callbackFunc2); ThrowIfNotEquals(true, RegisterCallbacks(ref callbacks), "Scenario 7: Struct with delegate marshalling failed"); #endif }
public void run(string projectDir, bool openGlTestEnabled) { try { // Create a C++ object and invoke some functions. { NTestClass obj = NTestClass.create("test1234ۆ"); checkEqual(obj.isNull(), false, "isNull() returned wrong value"); checkEqual(obj.getName(), "test1234ۆ", "Wrong name returned by getter"); checkEqual(obj.concatenateStrings("abcۆ", "defۆ"), "abcۆdefۆ", "Strings not concatenated correctly"); checkEqual(obj.concatenateStringsUtf16("ghiۆ", "jklۆ"), "ghiۆjklۆ", "UTF-16 strings not concatenated correctly"); // An exception can be propagated from C++ to C#. try { obj.throwException(); } catch (Exception e) { if (!e.Message.Contains("test_exception")) { throw new Exception("Got wrong exception from C++ function", e); } } // Vector math. checkEqual(obj.addFloatVectors(new Vector4(1, 2, 3, 4), new Vector4(5, 6, 7, 8)), new Vector4(6, 8, 10, 12), "Float vectors summed incorrectly"); checkEqual(obj.addFloatVectorsNoexcept(new Vector4(2, 3, 4, 5), new Vector4(6, 7, 8, 9)), new Vector4(8, 10, 12, 14), "Float vectors summed incorrectly (noexcept version)"); checkEqual(obj.getColor(new Vector2(1, 2)), new Vector4(2, 4, 4, 6), "getColor() returned wrong value"); // Destroy the object. obj.release(); checkEqual(NGlobal.partition2Test(), 22, "Partition 2 test function returned wrong value"); } // Subclasses. { NDerivedClass obj = NGlobal.createDerivedClassInstance(); checkEqual(obj.test1(), "derived1", "Overridden function returned wrong value"); checkEqual(obj.test3(), "base3", "Non-overridden function returned wrong value"); checkEqual(typeof(NDerivedClass).GetMethod("test2"), null, "test2() function should not be accessible because the base class was derived as private"); // A derived-class pointer can be converted to base-class pointer. NBaseClass1 basePtr = obj; checkEqual(basePtr.test1(), "derived1", "Overridden function returned wrong value when invoked with a base class pointer"); checkEqual(typeof(NBaseClass1).GetMethod("test3"), null, "Base class should not have functions that only exist in other base classes of the derived class"); obj.release(); } // Create a base class instance directly. { NBaseClass1 obj = NGlobal.createBaseClass1Instance(); checkEqual(obj.test1(), "base1", "Function from base class instance returned wrong value"); obj.release(); } // Create a struct and access its fields by a pointer from both C++ and C#. { TestStruct1 s = new TestStruct1(); string name = nameof(TestStruct1); checkEqual(s.i1, 0, $"{name} field i1 has wrong value before initialization"); NGlobal.setStruct1Values(&s); checkEqual(s.i1, 100, $"{name} field i1 has wrong value"); checkEqual(s.v1, new Vector4(1, 2, 3, 4), $"{name} field v1 has wrong value"); checkEqual(s.array1[1], 200, $"{name} field array1[1] has wrong value"); } { TestStruct2 s = new TestStruct2(); string name = nameof(TestStruct2); checkEqual(s.i, 0, $"{name} field i has wrong value before initialization"); NGlobal.setStruct2Values(&s); checkEqual(s.i, 100, $"{name} field s.i has wrong value"); } { CustomSharedStruct s = new CustomSharedStruct(); string name = nameof(CustomSharedStruct); checkEqual(s.i1, 0, $"{name} field i1 has wrong value before initialization"); NGlobal.setCustomSharedStructValues(&s); checkEqual(s.i1, 700, $"{name} field i1 has wrong value"); checkEqual(s.v1, new Vector4(10, 20, 30, 40), "Struct field v1 has wrong value"); } // Callback functions { NCallbackTest cbTest = NGlobal.createCallbackTestInstance(); checkEqual(cbTest.invokeGivenCallback("string5ۆ", "string6ۆ", (s1, s2) => s1 + s2), "string5ۆstring6ۆ", "C++ -> C# callback (given as parameter) should have concatenated strings"); checkEqual(cbTest.invokeGivenCallbackUtf16("string7ۆ", "string8ۆ", (s1, s2) => s1 + s2), "string7ۆstring8ۆ", "C++ -> C# callback (given as parameter) should have concatenated UTF-16 strings"); cbTest.setCallback((s1, s2) => s1 + s2); checkEqual(cbTest.invokeStoredCallback("string1ۆ", "string2ۆ"), "string1ۆstring2ۆ", "C++ -> C# callback (stored) should have concatenated strings"); } // Namespaces. { CsNamespace.CppOuterNamespace.NTestClass2 obj = NGlobal.createTestClass2Instance("test5678", 123); checkEqual(obj.getName(), "test5678", "Wrong name returned by getter"); checkEqual(obj.getIndex(), 123, "Wrong index returned by getter"); obj.release(); checkEqual(CsNamespace.CppOuterNamespace.NGlobal.calculateSum(1, CsNamespace.CppOuterNamespace.EnumInsideNamespace.TEST2), 3, "Wrong result from calculateSum()"); } { CsNamespace.CppOuterNamespace.CppInnerNamespace.NTestClass3 obj = NGlobal.createTestClass3Instance("test_abc"); checkEqual(obj.getName(), "test_abc", "Wrong name returned by getter"); obj.release(); CsNamespace.CppOuterNamespace.CppInnerNamespace.StructInsideNamespace s = new CsNamespace.CppOuterNamespace.CppInnerNamespace.StructInsideNamespace(); s.v = 7; checkEqual(CsNamespace.CppOuterNamespace.CppInnerNamespace.NGlobal.calculateProduct(5, s), 35, "Wrong result from calculateProduct()"); } // File set. { NGlobal.handleBicycle(new IncludedBicycleStruct()); NGlobal.handleVehicle(new IncludedVehicleStruct()); checkEqual(Type.GetType("CsNamespace.IncludedBicycleStruct") == null, false, "Struct from included file should be available"); checkEqual(Type.GetType("CsNamespace.ExcludedCarStruct") == null, true, "Struct from excluded file not exist"); checkEqual(Type.GetType("CsNamespace.ExcludedFileStruct") == null, true, "Struct from excluded file not exist"); } // Enum reflection in C++. { string result = NGlobal.testEnumReflection(); if (result.Length > 0) { throw new Exception($"Error in enum reflection test: {result}"); } } // OpenGL. if (openGlTestEnabled) { NGlobal.testOpenGl(projectDir); } else { Log.write("Skipping OpenGL test", null, ConsoleColor.Yellow); } Log.write("*** FUNCTIONAL TEST SUCCESS ***", null, ConsoleColor.Green); } catch (Exception e) { Log.write("*** FUNCTIONAL TEST FAILED ***", e, ConsoleColor.Red); } }
static int reg_struct_ret(TestStruct2 regStruct) { return(regStruct.b); }
static TestStruct2 struct_ret(TestStruct2 regStruct) { regStruct.a = -1; regStruct.b = 72; return(regStruct); }
/// <summary> /// 对 <see cref="Cyjb.TypeExt.IsImplicitFrom"/> 方法进行测试的辅助方法。 /// </summary> public void TestImplicitChangeTypeHelper(Func <object, Type, object> func) { object value = new object(); #region 6.1.1 标识转换 Assert.AreEqual(value, func(value, typeof(object))); value = true; Assert.AreEqual(value, func(value, typeof(bool))); value = 'A'; Assert.AreEqual(value, func(value, typeof(char))); value = (sbyte)10; Assert.AreEqual(value, func(value, typeof(sbyte))); value = (short)11; Assert.AreEqual(value, func(value, typeof(short))); value = (ushort)12; Assert.AreEqual(value, func(value, typeof(ushort))); value = (int)13; Assert.AreEqual(value, func(value, typeof(int))); value = (uint)14; Assert.AreEqual(value, func(value, typeof(uint))); value = (long)15; Assert.AreEqual(value, func(value, typeof(long))); value = (ulong)16; Assert.AreEqual(value, func(value, typeof(ulong))); value = (float)17; Assert.AreEqual(value, func(value, typeof(float))); value = (double)18; Assert.AreEqual(value, func(value, typeof(double))); value = (decimal)19; Assert.AreEqual(value, func(value, typeof(decimal))); value = new TestClass(); Assert.AreEqual(value, func(value, typeof(TestClass))); // 这里还有一点是 dynamic 和 object 是等效的,但由于在运行时 // dynamic 和 object 没有区别(参见规范 4.7 节), // 因此在判断类型转换时完全不用考虑它。 #endregion // 6.1.1 标识转换 #region 6.1.2 隐式数值转换 Assert.AreEqual((short)10, func((sbyte)10, typeof(short))); Assert.AreEqual((int)11, func((sbyte)11, typeof(int))); Assert.AreEqual((long)12, func((sbyte)12, typeof(long))); Assert.AreEqual((float)13, func((sbyte)13, typeof(float))); Assert.AreEqual((double)14, func((sbyte)14, typeof(double))); Assert.AreEqual((decimal)15, func((sbyte)15, typeof(decimal))); Assert.AreEqual((short)10, func((byte)10, typeof(short))); Assert.AreEqual((ushort)11, func((byte)11, typeof(ushort))); Assert.AreEqual((int)12, func((byte)12, typeof(int))); Assert.AreEqual((uint)13, func((byte)13, typeof(uint))); Assert.AreEqual((long)14, func((byte)14, typeof(long))); Assert.AreEqual((ulong)15, func((byte)15, typeof(ulong))); Assert.AreEqual((float)16, func((byte)16, typeof(float))); Assert.AreEqual((double)17, func((byte)17, typeof(double))); Assert.AreEqual((decimal)18, func((byte)18, typeof(decimal))); Assert.AreEqual((int)12, func((short)12, typeof(int))); Assert.AreEqual((long)14, func((short)14, typeof(long))); Assert.AreEqual((float)16, func((short)16, typeof(float))); Assert.AreEqual((double)17, func((short)17, typeof(double))); Assert.AreEqual((decimal)18, func((short)18, typeof(decimal))); Assert.AreEqual((int)12, func((ushort)12, typeof(int))); Assert.AreEqual((uint)13, func((ushort)13, typeof(uint))); Assert.AreEqual((long)14, func((ushort)14, typeof(long))); Assert.AreEqual((ulong)15, func((ushort)15, typeof(ulong))); Assert.AreEqual((float)16, func((ushort)16, typeof(float))); Assert.AreEqual((double)17, func((ushort)17, typeof(double))); Assert.AreEqual((decimal)18, func((ushort)18, typeof(decimal))); Assert.AreEqual((long)14, func((int)14, typeof(long))); Assert.AreEqual((float)16, func((int)16, typeof(float))); Assert.AreEqual((double)17, func((int)17, typeof(double))); Assert.AreEqual((decimal)18, func((int)18, typeof(decimal))); Assert.AreEqual((long)14, func((uint)14, typeof(long))); Assert.AreEqual((ulong)15, func((uint)15, typeof(ulong))); Assert.AreEqual((float)16, func((uint)16, typeof(float))); Assert.AreEqual((double)17, func((uint)17, typeof(double))); Assert.AreEqual((decimal)18, func((uint)18, typeof(decimal))); Assert.AreEqual((float)16, func((long)16, typeof(float))); Assert.AreEqual((double)17, func((long)17, typeof(double))); Assert.AreEqual((decimal)18, func((long)18, typeof(decimal))); Assert.AreEqual((float)16, func((ulong)16, typeof(float))); Assert.AreEqual((double)17, func((ulong)17, typeof(double))); Assert.AreEqual((decimal)18, func((ulong)18, typeof(decimal))); Assert.AreEqual((ushort)11, func((char)11, typeof(ushort))); Assert.AreEqual((int)12, func((char)12, typeof(int))); Assert.AreEqual((uint)13, func((char)13, typeof(uint))); Assert.AreEqual((long)14, func((char)14, typeof(long))); Assert.AreEqual((ulong)15, func((char)15, typeof(ulong))); Assert.AreEqual((float)16, func((char)16, typeof(float))); Assert.AreEqual((double)17, func((char)17, typeof(double))); Assert.AreEqual((decimal)18, func((char)18, typeof(decimal))); Assert.AreEqual((double)17, func((float)17, typeof(double))); #endregion // 6.1.2 隐式数值转换 // 6.1.3 隐式枚举转换,针对的是十进制数字文本 0,不在考虑范围内。 #region 6.1.4 可以为 null 的隐式转换 // 从 S 到 T? 的隐式转换。 Assert.AreEqual((int?)10, func((int)10, typeof(int?))); Assert.AreEqual((long?)10, func((int)10, typeof(long?))); // 从 S? 到 T? 的隐式转换。 Assert.AreEqual((int?)10, func((int?)10, typeof(int?))); Assert.AreEqual((long?)10, func((int?)10, typeof(long?))); Assert.AreEqual((long?)null, func((int?)null, typeof(long?))); #endregion // 6.1.4 可以为 null 的隐式转换 // 6.1.5 null 文本转换,不在考虑范围内。 #region 6.1.6 隐式引用转换 // 6.1.6.1 从任何 reference-type 到 object (和 dynamic)。 value = "abc"; Assert.AreEqual((object)value, func(value, typeof(object))); value = new TestClass(); Assert.AreEqual((object)value, func(value, typeof(object))); // 6.1.6.2 从任何 class-type S 到任何 class-type T(前提是 S 是从 T 派生的)。 value = new TestClass2(); Assert.AreEqual((TestClass)value, func(value, typeof(TestClass))); // 6.1.6.3 从任何 class-type S 到任何 interface-type T(前提是 S 实现了 T)。 value = new List <int>(); Assert.AreEqual((IList <int>)value, func(value, typeof(IList <int>))); // 6.1.6.4 从任何 interface-type S 到任何 interface-type T(前提是 S 是从 T 派生的)。 value = new List <int>(); Assert.AreEqual((IList)value, func(value, typeof(IList))); // 6.1.6.5 从元素类型为 SE 的 array-type S 到元素类型为 TE 的 array-type T(前提是以下所列条件均成立): // o S 和 T 只有元素类型不同。换言之,S 和 T 具有相同的维数。 // o SE 和 TE 都是 reference-type。 // o 存在从 SE 到 TE 的隐式引用转换。 value = new string[0]; Assert.AreEqual((object[])value, func(value, typeof(object[]))); value = new TestClass2[0]; Assert.AreEqual((TestClass[])value, func(value, typeof(TestClass[]))); value = new List <int> [0]; Assert.AreEqual((IList[])value, func(value, typeof(IList[]))); value = new List <string> [0]; Assert.AreEqual(value, func(value, typeof(IEnumerable <object>[]))); // 6.1.6.6 从任何 array-type 到 System.Array 及其实现的接口。 value = new int[0]; Assert.AreEqual((Array)value, func(value, typeof(Array))); value = new object[0]; Assert.AreEqual((Array)value, func(value, typeof(Array))); // 6.1.6.7 从一维数组类型 S[] 到 System.Collections.Generic.IList<T> 及其基接口 // (前提是存在从 S 到 T 的隐式标识或引用转换)。 value = new int[0]; Assert.AreEqual((IList <int>)value, func(value, typeof(IList <int>))); value = new TestClass[0][][]; Assert.AreEqual((IList <IList <TestClass>[]>)value, func(value, typeof(IList <IList <TestClass>[]>))); // 6.1.6.8 从任何 delegate-type 到 System.Delegate 及其实现的接口。 value = new Func <int>(TestMethod); Assert.AreEqual((Delegate)value, func((Delegate)value, typeof(Delegate))); // 6.1.6.9 从 null 文本到任何 reference-type,不在考虑范围内。 // 6.1.6.10 从任何 reference-type 到 reference-type T // (前提是它具有到 reference-type T0 的隐式标识或引用转换,且 T0 具有到 T 的标识转换)。 // 此条规则也可以不考虑。 // 6.1.6.11 从任何 reference-type 到接口或委托类型 T // (前提是它具有到接口或委托类型 T0 的隐式标识或引用转换,且 T0 可变化转换为T)。 // 这里的变化转换在规范的 13.1.3.2 节,就是泛型的协变和逆变。 // 协变。 value = Enumerable.Empty <string>(); Assert.AreEqual((IEnumerable <object>)value, func(value, typeof(IEnumerable <object>))); value = Enumerable.Empty <IEqualityComparer <object>[]>(); Assert.AreEqual((IEnumerable <IEqualityComparer <string>[]>)value, func(value, typeof(IEnumerable <IEqualityComparer <string>[]>))); value = Enumerable.Empty <object[][]>(); Assert.AreEqual((IEnumerable <IList <IList <object> > >)value, func(value, typeof(IEnumerable <IList <IList <object> > >))); // 逆变。 value = EqualityComparer <object> .Default; Assert.AreEqual((IEqualityComparer <string>)value, func(value, typeof(IEqualityComparer <string>))); value = EqualityComparer <IEnumerable <object>[]> .Default; Assert.AreEqual((IEqualityComparer <IEnumerable <string>[]>)value, func(value, typeof(IEqualityComparer <IEnumerable <string>[]>))); value = EqualityComparer <IList <TestClass[]> > .Default; Assert.AreEqual((IEqualityComparer <TestClass2[][]>)value, func(value, typeof(IEqualityComparer <TestClass2[][]>))); // 6.1.6.12 涉及已知为引用类型的类型参数的隐式转换。这个转换是针对类型参数 T 的,因此同样不做考虑。 #endregion // 6.1.6 隐式引用转换 #region 6.1.7 装箱转换 // 从 non-nullable-value-type 到 object。 value = (uint)10; Assert.AreEqual((object)value, func(value, typeof(object))); value = new TestStruct(); Assert.AreEqual((object)value, func(value, typeof(object))); // 从 non-nullable-value-type 到 System.ValueType。 value = 10; Assert.AreEqual((ValueType)value, func(value, typeof(ValueType))); value = new TestStruct2(); Assert.AreEqual((ValueType)value, func(value, typeof(ValueType))); // 从 non-nullable-value-type 到其实现的接口。 value = 10; Assert.AreEqual((IComparable <int>)value, func(value, typeof(IComparable <int>))); value = new TestStruct4(); Assert.AreEqual((IEnumerable <string>)value, func(value, typeof(IEnumerable <string>))); // 从 enum-type 转换为 System.Enum 类型。 value = Tristate.True; Assert.AreEqual((Enum)value, func(value, typeof(Enum))); // 从 nullable-type 到引用类型的装箱转换,如果存在从对应的 non-nullable-value-type 到该引用类型的装箱转换。 value = (uint?)10; Assert.AreEqual((object)value, func(value, typeof(object))); value = (int?)11; Assert.AreEqual((ValueType)value, func(value, typeof(ValueType))); value = (int?)null; Assert.AreEqual((ValueType)value, func(value, typeof(ValueType))); value = (int?)12; Assert.AreEqual((IComparable <int>)value, func(value, typeof(IComparable <int>))); value = (Tristate?)Tristate.True; Assert.AreEqual((Enum)value, func(value, typeof(Enum))); // 如果值类型具有到接口或委托类型 I0 的装箱转换,且 I0 变化转换为接口类型 I,则值类型具有到 I 的装箱转换。 value = new TestStruct4(); Assert.AreEqual((IEnumerable <object>)value, func(value, typeof(IEnumerable <object>))); value = (TestStruct4?)new TestStruct4(); Assert.AreEqual((IEnumerable <object>)value, func(value, typeof(IEnumerable <object>))); value = (TestStruct4?)null; Assert.AreEqual((IEnumerable <object>)value, func(value, typeof(IEnumerable <object>))); #endregion // 6.1.7 装箱转换 // 6.1.8 隐式动态转换、6.1.9 隐式常量表达式转换、6.1.10 涉及类型形参的隐式转换,不在考虑范围内。 #region 6.1.11 用户定义的隐式转换 value = new TestStruct2(); object expectedValue = (TestStruct) new TestStruct2(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct))); value = new TestStruct2(); expectedValue = (TestStruct?)new TestStruct2(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct2?)new TestStruct2(); expectedValue = (TestStruct?)(TestStruct2?)new TestStruct2(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct2?)null; Assert.AreEqual((TestStruct?)value, func(value, typeof(TestStruct?))); value = new TestStruct3(); expectedValue = (TestStruct) new TestStruct3(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct))); value = new TestStruct3(); expectedValue = (TestStruct?)new TestStruct3(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct3?)new TestStruct3(); expectedValue = (TestStruct?)(TestStruct3?)new TestStruct3(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct3?)null; Assert.AreEqual(value, func(value, typeof(TestStruct?))); value = new TestStruct5(); expectedValue = (TestStruct?)new TestStruct5(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = new TestStruct6(); expectedValue = (TestStruct) new TestStruct6(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct))); value = (TestStruct6?)new TestStruct6(); expectedValue = (TestStruct)(TestStruct6?)new TestStruct6(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct))); value = new TestStruct6(); expectedValue = (TestStruct?)new TestStruct6(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct6?)new TestStruct6(); expectedValue = (TestStruct?)(TestStruct6?)new TestStruct6(); Assert.AreEqual(expectedValue, func(value, typeof(TestStruct?))); value = (TestStruct6?)null; Assert.AreEqual(value, func(value, typeof(TestStruct?))); value = new TestClass(); expectedValue = (int)new TestClass(); Assert.AreEqual(expectedValue, func(value, typeof(int))); value = new TestClass2(); expectedValue = (int)new TestClass2(); Assert.AreEqual(expectedValue, func(value, typeof(int))); value = new TestClass2(); expectedValue = (long)new TestClass2(); Assert.AreEqual(expectedValue, func(value, typeof(long))); value = new TestClass2(); expectedValue = (bool)new TestClass2(); Assert.AreEqual(expectedValue, func(value, typeof(bool))); value = new TestClass13(); expectedValue = (Enum) new TestClass13(); Assert.AreEqual(expectedValue, func(value, typeof(Enum))); value = new TestClass12(); expectedValue = (int?)new TestClass12(); Assert.AreEqual(expectedValue, func(value, typeof(int?))); value = new TestClass8(); expectedValue = (TestClass6) new TestClass8(); Assert.AreEqual(expectedValue, func(value, typeof(TestClass6))); value = new TestClass6(); expectedValue = (TestClass7) new TestClass6(); Assert.AreEqual(expectedValue, func(value, typeof(TestClass7))); value = 10; expectedValue = (TestClass6)10; Assert.AreEqual(expectedValue, func(value, typeof(TestClass6))); value = new TestClass(); expectedValue = (long)new TestClass(); Assert.AreEqual(expectedValue, func(value, typeof(long))); value = new TestClass(); expectedValue = (decimal) new TestClass(); Assert.AreEqual(expectedValue, func(value, typeof(decimal))); value = new TestClass2(); expectedValue = (decimal) new TestClass2(); Assert.AreEqual(expectedValue, func(value, typeof(decimal))); value = (short)10; expectedValue = (TestClass6)(short)10; Assert.AreEqual(expectedValue, func(value, typeof(TestClass6))); value = new TestClass6(); expectedValue = (long)new TestClass6(); Assert.AreEqual(expectedValue, func(value, typeof(long))); #endregion // 6.1.11 用户定义的隐式转换 }