diff --git a/CPPInterop.sln b/CPPInterop.sln index dde0c0bb..532d9b1b 100644 --- a/CPPInterop.sln +++ b/CPPInterop.sln @@ -7,6 +7,8 @@ Project("{2857B73E-F847-4B02-9238-064979017E93}") = "CPPTestLib", "CPPTestLib\CP EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{3C290CBE-CA39-47F6-B3A0-ACD16C5A38C8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDebugHarness", "TestDebugHarness\TestDebugHarness.csproj", "{AD562CD3-5DEB-4D19-9819-5279C0649AE8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {4A864586-93C5-4DC1-8A80-F094A88506D7}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A864586-93C5-4DC1-8A80-F094A88506D7}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A864586-93C5-4DC1-8A80-F094A88506D7}.Release|Any CPU.Build.0 = Release|Any CPU + {AD562CD3-5DEB-4D19-9819-5279C0649AE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD562CD3-5DEB-4D19-9819-5279C0649AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD562CD3-5DEB-4D19-9819-5279C0649AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD562CD3-5DEB-4D19-9819-5279C0649AE8}.Release|Any CPU.Build.0 = Release|Any CPU {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.Build.0 = Debug|Any CPU {B01E6282-144E-481A-8E1F-95F708DFBC2D}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/CPPTestLib/CPPTestLib.cproj b/CPPTestLib/CPPTestLib.cproj index 41c3e0c9..9b97e57e 100644 --- a/CPPTestLib/CPPTestLib.cproj +++ b/CPPTestLib/CPPTestLib.cproj @@ -35,5 +35,10 @@ + + + + + \ No newline at end of file diff --git a/CPPTestLib/CSimpleClass.cpp b/CPPTestLib/CSimpleClass.cpp index 34ae83b3..917be8d1 100644 --- a/CPPTestLib/CSimpleClass.cpp +++ b/CPPTestLib/CSimpleClass.cpp @@ -8,11 +8,9 @@ */ #include +#include "NUnit.h" -/* The classes below are exported */ -#pragma GCC visibility push(default) - -class CSimpleClass { +class EXPORT CSimpleClass { public: int value; CSimpleClass (int value) : value (value) @@ -54,7 +52,7 @@ public: } }; -class CSimpleSubClass : CSimpleClass { +class EXPORT CSimpleSubClass : CSimpleClass { public: CSimpleSubClass (int value) : CSimpleClass (value) { @@ -82,5 +80,3 @@ extern "C" { delete obj; } } - -#pragma GCC visibility pop diff --git a/CPPTestLib/NUnit.cpp b/CPPTestLib/NUnit.cpp new file mode 100644 index 00000000..9cda8f0f --- /dev/null +++ b/CPPTestLib/NUnit.cpp @@ -0,0 +1,13 @@ + +#include "TestFramework.h" + +NUnit* NUnit::Assert; + +extern "C" { + + void SetNUnitInterface (NUnit* nunit) + { + NUnit::Assert = nunit; + } + +} diff --git a/CPPTestLib/NUnit.h b/CPPTestLib/NUnit.h new file mode 100644 index 00000000..ac12a5de --- /dev/null +++ b/CPPTestLib/NUnit.h @@ -0,0 +1,106 @@ + +#ifndef _CPPINTEROP_TESTFRAMEWORK_H_ +#define _CPPINTEROP_TESTFRAMEWORK_H_ + +#ifdef __GNUC__ +#define EXPORT +#elif defined(_MSC_VER) +#define EXPORT __declspec(dllexport) +#else +#error Unknown compiler! +#endif + +typedef const char* string; +typedef unsigned int uint; +typedef unsigned long ulong; + +class NUnit { + public: + static NUnit* Assert; + + virtual void Fail (string message); + virtual void Fail (); + virtual void IsTrue (bool condition, string message); + virtual void IsTrue (bool condition); + virtual void IsFalse (bool condition, string message); + virtual void IsFalse (bool condition); + virtual void IsEmpty (string aString, string message); + virtual void IsEmpty (string aString); + virtual void IsNotEmpty (string aString, string message); + virtual void IsNotEmpty (string aString); + virtual void AreEqual (int expected, int actual, string message); + virtual void AreEqual (int expected, int actual); + virtual void AreEqual (long expected, long actual, string message); + virtual void AreEqual (long expected, long actual); + virtual void AreEqual (uint expected, uint actual, string message); + virtual void AreEqual (uint expected, uint actual); + virtual void AreEqual (ulong expected, ulong actual, string message); + virtual void AreEqual (ulong expected, ulong actual); + virtual void AreEqual (double expected, double actual, double delta, string message); + virtual void AreEqual (double expected, double actual, double delta); + virtual void AreEqual (float expected, float actual, float delta, string message); + virtual void AreEqual (float expected, float actual, float delta); + virtual void AreNotEqual (int expected, int actual, string message); + virtual void AreNotEqual (int expected, int actual); + virtual void AreNotEqual (long expected, long actual, string message); + virtual void AreNotEqual (long expected, long actual); + virtual void AreNotEqual (uint expected, uint actual, string message); + virtual void AreNotEqual (uint expected, uint actual); + virtual void AreNotEqual (ulong expected, ulong actual, string message); + virtual void AreNotEqual (ulong expected, ulong actual); + virtual void AreNotEqual (double expected, double actual, string message); + virtual void AreNotEqual (double expected, double actual); + virtual void AreNotEqual (float expected, float actual, string message); + virtual void AreNotEqual (float expected, float actual); + virtual void Greater (int expected, int actual, string message); + virtual void Greater (int expected, int actual); + virtual void Greater (long expected, long actual, string message); + virtual void Greater (long expected, long actual); + virtual void Greater (uint expected, uint actual, string message); + virtual void Greater (uint expected, uint actual); + virtual void Greater (ulong expected, ulong actual, string message); + virtual void Greater (ulong expected, ulong actual); + virtual void Greater (double expected, double actual, string message); + virtual void Greater (double expected, double actual); + virtual void Greater (float expected, float actual, string message); + virtual void Greater (float expected, float actual); + virtual void Less (int expected, int actual, string message); + virtual void Less (int expected, int actual); + virtual void Less (long expected, long actual, string message); + virtual void Less (long expected, long actual); + virtual void Less (uint expected, uint actual, string message); + virtual void Less (uint expected, uint actual); + virtual void Less (ulong expected, ulong actual, string message); + virtual void Less (ulong expected, ulong actual); + virtual void Less (double expected, double actual, string message); + virtual void Less (double expected, double actual); + virtual void Less (float expected, float actual, string message); + virtual void Less (float expected, float actual); + virtual void GreaterOrEqual (int expected, int actual, string message); + virtual void GreaterOrEqual (int expected, int actual); + virtual void GreaterOrEqual (long expected, long actual, string message); + virtual void GreaterOrEqual (long expected, long actual); + virtual void GreaterOrEqual (uint expected, uint actual, string message); + virtual void GreaterOrEqual (uint expected, uint actual); + virtual void GreaterOrEqual (ulong expected, ulong actual, string message); + virtual void GreaterOrEqual (ulong expected, ulong actual); + virtual void GreaterOrEqual (double expected, double actual, string message); + virtual void GreaterOrEqual (double expected, double actual); + virtual void GreaterOrEqual (float expected, float actual, string message); + virtual void GreaterOrEqual (float expected, float actual); + virtual void LessOrEqual (int expected, int actual, string message); + virtual void LessOrEqual (int expected, int actual); + virtual void LessOrEqual (long expected, long actual, string message); + virtual void LessOrEqual (long expected, long actual); + virtual void LessOrEqual (uint expected, uint actual, string message); + virtual void LessOrEqual (uint expected, uint actual); + virtual void LessOrEqual (ulong expected, ulong actual, string message); + virtual void LessOrEqual (ulong expected, ulong actual); + virtual void LessOrEqual (double expected, double actual, string message); + virtual void LessOrEqual (double expected, double actual); + virtual void LessOrEqual (float expected, float actual, string message); + virtual void LessOrEqual (float expected, float actual); +}; + + +#endif /* _CPPINTEROP_TESTFRAMEWORK_H_ */ diff --git a/CPPTestLib/VirtualMethodTestClass.cpp b/CPPTestLib/VirtualMethodTestClass.cpp new file mode 100644 index 00000000..ded14331 --- /dev/null +++ b/CPPTestLib/VirtualMethodTestClass.cpp @@ -0,0 +1,25 @@ + +#include "NUnit.h" + +class EXPORT VirtualMethodTestClass { + + virtual void V0 (int a1, int a2, int a3) + { + NUnit::Assert->AreEqual (1, a1, "V0 #A1"); + NUnit::Assert->AreEqual (2, a2, "V0 #A2"); + NUnit::Assert->AreEqual (3, a3, "V0 #A3"); + } + +}; + +extern "C" { + VirtualMethodTestClass* CreateVirtualMethodTestClass () + { + return new VirtualMethodTestClass (); + } + + void DestroyVirtualMethodTestClass (VirtualMethodTestClass* vmtc) + { + delete vmtc; + } +} diff --git a/Mono.VisualC.Interop/ABI/CppAbi.cs b/Mono.VisualC.Interop/ABI/CppAbi.cs index cc430ff7..8c5abbe8 100644 --- a/Mono.VisualC.Interop/ABI/CppAbi.cs +++ b/Mono.VisualC.Interop/ABI/CppAbi.cs @@ -136,9 +136,8 @@ namespace Mono.VisualC.Interop.ABI { protected virtual void DefineImplType () { - - impl_type = impl_module.DefineType (interface_type.Name + "_" + layout_type.Name + "_Impl", - TypeAttributes.Class | TypeAttributes.Sealed); + string implTypeName = interface_type.Name + "_" + layout_type.Name + "_" + this.GetType ().Name + "_Impl"; + impl_type = impl_module.DefineType (implTypeName, TypeAttributes.Class | TypeAttributes.Sealed); impl_type.AddInterfaceImplementation (interface_type); vtable_field = impl_type.DefineField ("_vtable", typeof (VTable), FieldAttributes.InitOnly | FieldAttributes.Private); @@ -267,6 +266,9 @@ namespace Mono.VisualC.Interop.ABI { */ protected virtual Delegate GetManagedOverrideTrampoline (MethodInfo interfaceMethod, MemberFilter binder) { + if (wrapper_type == null) + return null; + MethodInfo targetMethod = FindManagedOverrideTarget (interfaceMethod, binder); if (targetMethod == null) return null; @@ -285,12 +287,12 @@ namespace Mono.VisualC.Interop.ABI { // for static methods: OpCode callInstruction = OpCodes.Call; - int argLoadStart = 0; + int argLoadStart = 1; // for instance methods, we need an instance to call them on! if (!targetMethod.IsStatic) { callInstruction = OpCodes.Callvirt; - argLoadStart = 1; + //argLoadStart = 1; il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldc_I4, NativeSize); diff --git a/Mono.VisualC.Interop/CppInstancePtr.cs b/Mono.VisualC.Interop/CppInstancePtr.cs index 6eb13f1a..dd260dc1 100644 --- a/Mono.VisualC.Interop/CppInstancePtr.cs +++ b/Mono.VisualC.Interop/CppInstancePtr.cs @@ -22,6 +22,8 @@ namespace Mono.VisualC.Interop { private static Dictionary implCache = new Dictionary (); + // TODO: the managed instance argument may only be NULL if all methods in TWrapper + // that correspond to the virtual methods in Iface are static. public static CppInstancePtr ForManagedObject (TWrapper managed) where Iface : ICppClassOverridable { diff --git a/Mono.VisualC.Interop/CppLibrary.cs b/Mono.VisualC.Interop/CppLibrary.cs index bd0b62c6..114baca3 100644 --- a/Mono.VisualC.Interop/CppLibrary.cs +++ b/Mono.VisualC.Interop/CppLibrary.cs @@ -55,7 +55,17 @@ namespace Mono.VisualC.Interop { get { return abi; } } - // For a class that may have fields with no virtual methods to be overridden + // For working with a class that you are not instantiating + // from managed code and where access to fields is not necessary + public Iface GetClass (string className) + where Iface : ICppClass + { + + return Abi.ImplementClass (null, Name, className); + } + + // For instantiating or working with a class that may have fields + // but where overriding virtual methods in managed code is not necessary public Iface GetClass (string className) where Iface : ICppClassInstantiatable where NativeLayout : struct @@ -64,7 +74,11 @@ namespace Mono.VisualC.Interop { return Abi.ImplementClass (null, Name, className); } - // For a class that may have fields and virtual methods to be overridden + /* The most powerful override. Allows the following from managed code: + * + Instantiation + * + Field access + * + Virtual method overriding + */ public Iface GetClass (string className) where Iface : ICppClassOverridable where NativeLayout : struct @@ -73,9 +87,6 @@ namespace Mono.VisualC.Interop { return Abi.ImplementClass (typeof (Managed), Name, className); } - // TODO: Define a method for pure virtual classes (no NativeLayout)? - - - } + } } diff --git a/Mono.VisualC.Interop/Interfaces.cs b/Mono.VisualC.Interop/Interfaces.cs index b2e49fa0..b930eaa1 100644 --- a/Mono.VisualC.Interop/Interfaces.cs +++ b/Mono.VisualC.Interop/Interfaces.cs @@ -17,11 +17,11 @@ namespace Mono.VisualC.Interop { public interface ICppClass { VTable ClassVTable { get; } - void Destruct (CppInstancePtr instance); } public interface ICppClassInstantiatable : ICppClass { CppInstancePtr Alloc (); + void Destruct (CppInstancePtr instance); } // It is recommended that managed wrappers implement ICppObject, but @@ -29,5 +29,6 @@ namespace Mono.VisualC.Interop { // C++ via CppInstancePtr.ForManagedObject. public interface ICppClassOverridable : ICppClass /* where T : ICppObject */ { CppInstancePtr Alloc (T managed); + void Destruct (CppInstancePtr instance); } } \ No newline at end of file diff --git a/Mono.VisualC.Interop/Util.cs b/Mono.VisualC.Interop/Util.cs index 8e43b6a4..d576c8c1 100644 --- a/Mono.VisualC.Interop/Util.cs +++ b/Mono.VisualC.Interop/Util.cs @@ -12,9 +12,14 @@ namespace Mono.VisualC.Interop { public static Type GetDelegateTypeForMethodInfo (ModuleBuilder mod, MethodInfo targetMethod) { + // TODO: Actually return the same delegate type instead of creating a new one if + // a suitable type already exists?? + string delTypeName = mod.Name + "_" + targetMethod.Name + "_VTdel"; + while (mod.GetType (delTypeName) != null) + delTypeName += "_"; TypeAttributes typeAttr = TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass; - TypeBuilder del = mod.DefineType (mod.Name + "_" + targetMethod.Name + "_VTdel", typeAttr, typeof(MulticastDelegate)); + TypeBuilder del = mod.DefineType (delTypeName, typeAttr, typeof(MulticastDelegate)); MethodAttributes ctorAttr = MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public; diff --git a/Tests/CppInstancePtrTests.cs b/Tests/CppInstancePtrTests.cs index 4d1f8876..602fff17 100644 --- a/Tests/CppInstancePtrTests.cs +++ b/Tests/CppInstancePtrTests.cs @@ -16,7 +16,7 @@ using Tests.Support; namespace Tests { [TestFixture] - public class CppInstancePtrTests : CPPTestLibBase { + public class CppInstancePtrTests { static CppInstancePtr uninitialized; @@ -24,16 +24,24 @@ namespace Tests { [ExpectedException (typeof (ObjectDisposedException))] public void TestUninitialized () { - Assert.IsFalse (uninitialized.IsManagedAlloc, "cppip.IsManagedAlloc"); - Assert.AreEqual (IntPtr.Zero, uninitialized.Native, "cppip.Native wasn't null pointer"); + Assert.IsFalse (uninitialized.IsManagedAlloc, "#A1"); + Assert.AreEqual (IntPtr.Zero, uninitialized.Native, "#A2"); } [Test] public void TestForManagedObject () { - CppInstancePtr cppip = CppInstancePtr.ForManagedObject (this); - Assert.AreNotEqual (IntPtr.Zero, cppip.Native, "cppip.Native was null pointer"); - Assert.IsTrue (cppip.IsManagedAlloc, "cppip.IsManagedAlloc was not true"); + CppInstancePtr cppip = CppInstancePtr.ForManagedObject (CppMockObject.Instance); + Assert.AreNotEqual (IntPtr.Zero, cppip.Native, "#A1"); + Assert.IsTrue (cppip.IsManagedAlloc, "#A2"); + cppip.Dispose (); + } + + [Test] + [ExpectedException (typeof(ArgumentNullException))] + public void TestForNonStaticWrapperWithNull () + { + CppInstancePtr cppip = CppInstancePtr.ForManagedObject (null); cppip.Dispose (); } @@ -41,7 +49,7 @@ namespace Tests { [ExpectedException (typeof (ObjectDisposedException))] public void TestDisposed () { - CppInstancePtr cppip = CppInstancePtr.ForManagedObject (this); + CppInstancePtr cppip = CppInstancePtr.ForManagedObject (CppMockObject.Instance); cppip.Dispose (); // should throw Console.WriteLine (cppip.Native); @@ -53,7 +61,7 @@ namespace Tests { IntPtr native = CreateCSimpleSubClass (0); CppInstancePtr cppip = new CppInstancePtr (native); Assert.AreEqual (native, cppip.Native); - Assert.IsFalse (cppip.IsManagedAlloc, "cppip.IsManagedAlloc was not false"); + Assert.IsFalse (cppip.IsManagedAlloc, "#A1"); cppip.Dispose (); DestroyCSimpleSubClass (native); } diff --git a/Tests/CppLibraryTests.cs b/Tests/CppLibraryTests.cs index 153a0af4..c4f0c580 100644 --- a/Tests/CppLibraryTests.cs +++ b/Tests/CppLibraryTests.cs @@ -17,7 +17,7 @@ using Tests.Support; namespace Tests { [TestFixture] - public class CppLibraryTests : CPPTestLibBase { + public class CppLibraryTests { [Test] [ExpectedException (typeof (ArgumentNullException))] @@ -47,7 +47,7 @@ namespace Tests { { VirtualOnlyAbi abi = new VirtualOnlyAbi (); CppLibrary cppl = new CppLibrary ("FooLib", abi); - EmptyTestInterface klass = cppl.GetClass ("FooClass"); + EmptyTestInterface klass = cppl.GetClass ("FooClass"); Assert.IsNotNull (klass, "#A1"); } } diff --git a/Tests/ItaniumAbiTests.cs b/Tests/ItaniumAbiTests.cs index 9366208e..81c069d7 100644 --- a/Tests/ItaniumAbiTests.cs +++ b/Tests/ItaniumAbiTests.cs @@ -10,17 +10,16 @@ using System; using NUnit.Framework; -using Mono.VisualC.Interop; using Mono.VisualC.Interop.ABI; -using Tests.Support; namespace Tests { [TestFixture] - public class ItaniumAbiTests : CPPTestLibBase { + public class ItaniumAbiTests : SharedAbiTests { public ItaniumAbiTests () : base (new ItaniumAbi ()) { } + } } diff --git a/Tests/MsvcAbiTests.cs b/Tests/MsvcAbiTests.cs index bc09e5e9..5578128e 100644 --- a/Tests/MsvcAbiTests.cs +++ b/Tests/MsvcAbiTests.cs @@ -10,13 +10,11 @@ using System; using NUnit.Framework; -using Mono.VisualC.Interop; using Mono.VisualC.Interop.ABI; -using Tests.Support; namespace Tests { [TestFixture] - public class MsvcAbiTests : CPPTestLibBase { + public class MsvcAbiTests : SharedAbiTests { public MsvcAbiTests () : base (new MsvcAbi ()) { diff --git a/Tests/SharedAbiTests.cs b/Tests/SharedAbiTests.cs new file mode 100644 index 00000000..06e1221b --- /dev/null +++ b/Tests/SharedAbiTests.cs @@ -0,0 +1,34 @@ +using System; +using NUnit.Framework; + +using Mono.VisualC.Interop; +using Mono.VisualC.Interop.ABI; + +using Tests.Support; + +namespace Tests { + public class SharedAbiTests { + + protected CppLibrary test_lib { get; private set; } + protected IVirtualMethodTestClass virtual_test_class { get; private set; } + + protected SharedAbiTests (CppAbi abi) + { + this.test_lib = new CppLibrary ("CPPTestLib", abi); + this.virtual_test_class = test_lib.GetClass ("VirtualMethodTestClass"); + CppNUnitAsserts.Init (); + } + + [Test] + public void TestVirtualMethods () + { + CppInstancePtr vmtc = VirtualMethodTestClass.Create (); + + virtual_test_class.V0 (vmtc, 1, 2, 3); + + VirtualMethodTestClass.Destroy (vmtc); + } + + } +} + diff --git a/Tests/Support/CPPTestLibBase.cs b/Tests/Support/CPPTestLibBase.cs deleted file mode 100644 index 7df1b449..00000000 --- a/Tests/Support/CPPTestLibBase.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using NUnit.Framework; - -using Mono.VisualC.Interop; -using Mono.VisualC.Interop.ABI; - -namespace Tests.Support { - public class CPPTestLibBase : ICppObject { - - protected CppLibrary TestLib { get; private set; } - - protected CPPTestLibBase () - { - } - - protected CPPTestLibBase (CppAbi abi) - { - this.TestLib = new CppLibrary ("CPPTestLib", abi); - } - - - protected CSimpleClass.ICSimpleClass Klass { - get { - if (CSimpleClass._impl == null) - CSimpleClass.Bind (TestLib); - return CSimpleClass._impl; - } - } - public IntPtr Native { - get { - throw new System.NotImplementedException (); - } - } - - public void Dispose () - { - throw new System.NotImplementedException (); - } - - - } - - public interface EmptyTestInterface : ICppClassOverridable { - } - - public struct EmptyTestStruct { - } -} - diff --git a/Tests/Support/CSimpleClass.cs b/Tests/Support/CSimpleClass.cs index b6bc0836..4d01fe4d 100644 --- a/Tests/Support/CSimpleClass.cs +++ b/Tests/Support/CSimpleClass.cs @@ -35,65 +35,64 @@ namespace Tests.Support { } #endregion - public static ICSimpleClass _impl; + private CppInstancePtr native; + private ICSimpleClass impl; - public static void Bind(CppLibrary lib) { - _impl = lib.GetClass("CSimpleClass"); + public CSimpleClass(ICSimpleClass impl, int value) { + this.impl = impl; + this.native = impl.Alloc(this); + impl.CSimpleClass(native, value); } - private CppInstancePtr _native; - - public CSimpleClass(int value) { - _native = _impl.Alloc(this); - _impl.CSimpleClass(_native, value); + public CSimpleClass(ICSimpleClass impl, IntPtr native) { + this.impl = impl; + this.native = native; } - public CSimpleClass(IntPtr native) { - _native = native; + public IntPtr Native { + get { return (IntPtr)native; } } - public virtual IntPtr Native { - get { - return (IntPtr)_native; - } - } + public ICSimpleClass Implementation { + get { return impl; } + } public virtual int value { get { - return _impl.value[_native]; + return impl.value[native]; } set { - _impl.value[_native] = value; + impl.value[native] = value; } } public void M0() { - _impl.M0(_native); + impl.M0(native); } public void M1(int x) { - _impl.M1(_native, x); + impl.M1(native, x); } public void M2(int x, int y) { - _impl.M2(_native, x, y); + impl.M2(native, x, y); } [OverrideNative] public virtual void V0(int x, int y) { Console.WriteLine("Managed V0({0}, {1})", x, y); - _impl.V0(_native, x, y); + impl.V0(native, x, y); } [OverrideNative] public virtual void V1(int x) { Console.WriteLine("Managed V1({0})", x); - _impl.V1(_native, x); + impl.V1(native, x); } public void Dispose() { - _impl.Destruct(_native); - _native.Dispose(); + impl.Destruct(native); + native.Dispose(); } } diff --git a/Tests/Support/CppMockObject.cs b/Tests/Support/CppMockObject.cs new file mode 100644 index 00000000..01fb4e71 --- /dev/null +++ b/Tests/Support/CppMockObject.cs @@ -0,0 +1,45 @@ +// +// CPPTestLibBase.cs: Base class for supporting tests using CPPTestLib +// +// Author: +// Alexander Corrado (alexander.corrado@gmail.com) +// +// Copyright (C) 2010 Alexander Corrado +// + +using System; +using NUnit.Framework; + +using Mono.VisualC.Interop; +using Mono.VisualC.Interop.ABI; + +namespace Tests.Support { + public class CppMockObject : ICppObject { + + public static CppMockObject Instance = new CppMockObject (); + + protected CppMockObject () + { + } + + public IntPtr Native { + get { + throw new System.NotImplementedException (); + } + } + + public void Dispose () + { + throw new System.NotImplementedException (); + } + + + } + + public interface EmptyTestInterface : ICppClassOverridable { + } + + public struct EmptyTestStruct { + } +} + diff --git a/Tests/Support/CppNUnitAsserts.cs b/Tests/Support/CppNUnitAsserts.cs new file mode 100644 index 00000000..e5ab96db --- /dev/null +++ b/Tests/Support/CppNUnitAsserts.cs @@ -0,0 +1,107 @@ +using System; +using System.Runtime.InteropServices; +using NUnit.Framework; +using Mono.VisualC.Interop; + +namespace Tests.Support { + public static class CppNUnitAsserts { + + private interface IAssert : ICppClassOverridable { + [Virtual] void Fail (CppInstancePtr @this, string message); + [Virtual] void Fail (CppInstancePtr @this); + [Virtual] void IsTrue (CppInstancePtr @this, bool condition, string message); + [Virtual] void IsTrue (CppInstancePtr @this, bool condition); + [Virtual] void IsFalse (CppInstancePtr @this, bool condition, string message); + [Virtual] void IsFalse (CppInstancePtr @this, bool condition); + [Virtual] void IsEmpty (CppInstancePtr @this, string aString, string message); + [Virtual] void IsEmpty (CppInstancePtr @this, string aString); + [Virtual] void IsNotEmpty (CppInstancePtr @this, string aString, string message); + [Virtual] void IsNotEmpty (CppInstancePtr @this, string aString); + [Virtual] void AreEqual (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void AreEqual (CppInstancePtr @this, int expected, int actual); + [Virtual] void AreEqual (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void AreEqual (CppInstancePtr @this, long expected, long actual); + [Virtual] void AreEqual (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void AreEqual (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void AreEqual (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void AreEqual (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void AreEqual (CppInstancePtr @this, double expected, double actual, double delta, string message); + [Virtual] void AreEqual (CppInstancePtr @this, double expected, double actual, double delta); + [Virtual] void AreEqual (CppInstancePtr @this, float expected, float actual, float delta, string message); + [Virtual] void AreEqual (CppInstancePtr @this, float expected, float actual, float delta); + [Virtual] void AreNotEqual (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, int expected, int actual); + [Virtual] void AreNotEqual (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, long expected, long actual); + [Virtual] void AreNotEqual (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void AreNotEqual (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void AreNotEqual (CppInstancePtr @this, double expected, double actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, double expected, double actual); + [Virtual] void AreNotEqual (CppInstancePtr @this, float expected, float actual, string message); + [Virtual] void AreNotEqual (CppInstancePtr @this, float expected, float actual); + [Virtual] void Greater (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void Greater (CppInstancePtr @this, int expected, int actual); + [Virtual] void Greater (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void Greater (CppInstancePtr @this, long expected, long actual); + [Virtual] void Greater (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void Greater (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void Greater (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void Greater (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void Greater (CppInstancePtr @this, double expected, double actual, string message); + [Virtual] void Greater (CppInstancePtr @this, double expected, double actual); + [Virtual] void Greater (CppInstancePtr @this, float expected, float actual, string message); + [Virtual] void Greater (CppInstancePtr @this, float expected, float actual); + [Virtual] void Less (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void Less (CppInstancePtr @this, int expected, int actual); + [Virtual] void Less (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void Less (CppInstancePtr @this, long expected, long actual); + [Virtual] void Less (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void Less (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void Less (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void Less (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void Less (CppInstancePtr @this, double expected, double actual, string message); + [Virtual] void Less (CppInstancePtr @this, double expected, double actual); + [Virtual] void Less (CppInstancePtr @this, float expected, float actual, string message); + [Virtual] void Less (CppInstancePtr @this, float expected, float actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, int expected, int actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, long expected, long actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, double expected, double actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, double expected, double actual); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, float expected, float actual, string message); + [Virtual] void GreaterOrEqual (CppInstancePtr @this, float expected, float actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, int expected, int actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, int expected, int actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, long expected, long actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, long expected, long actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, uint expected, uint actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, uint expected, uint actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, ulong expected, ulong actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, ulong expected, ulong actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, double expected, double actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, double expected, double actual); + [Virtual] void LessOrEqual (CppInstancePtr @this, float expected, float actual, string message); + [Virtual] void LessOrEqual (CppInstancePtr @this, float expected, float actual); + } + + private static CppInstancePtr? nunitInterface; + public static void Init () + { + if (!nunitInterface.HasValue) + nunitInterface = CppInstancePtr.ForManagedObject (null); + + SetNUnitInterface ((IntPtr)nunitInterface.Value); + } + + [DllImport("CPPTestLib")] + private static extern void SetNUnitInterface (IntPtr nunit); + } +} + diff --git a/Tests/Support/VirtualMethodTestClass.cs b/Tests/Support/VirtualMethodTestClass.cs new file mode 100644 index 00000000..ab0352ae --- /dev/null +++ b/Tests/Support/VirtualMethodTestClass.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; +using Mono.VisualC.Interop; + +namespace Tests +{ + public interface IVirtualMethodTestClass : ICppClass { + [Virtual] void V0 (CppInstancePtr @this, int a1, int a2, int a3); + } + + public static class VirtualMethodTestClass { + + public static CppInstancePtr Create () + { + return CreateVirtualMethodTestClass (); + } + + public static void Destroy (CppInstancePtr vmtc) + { + DestroyVirtualMethodTestClass ((IntPtr)vmtc); + } + + + [DllImport("CPPTestLib")] + private static extern IntPtr CreateVirtualMethodTestClass (); + + [DllImport("CPPTestLib")] + private static extern void DestroyVirtualMethodTestClass (IntPtr vmtc); + } + +} + diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index fc5f90bc..4f2f4824 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -38,11 +38,14 @@ - + + + +