diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 299a3156..e4f5a24d 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1766,6 +1766,21 @@ namespace CppSharp.Generators.CSharp WriteLine("void Dispose(bool disposing)"); WriteStartBraceIndent(); + const string destroyNativeInstance = "DestroyNativeInstance"; + WriteLine("{0}(false);", destroyNativeInstance); + if (hasBaseClass) + WriteLine("base.Dispose(disposing);"); + WriteCloseBraceIndent(); + NewLine(); + + WriteLine("public void {0}()", destroyNativeInstance); + WriteStartBraceIndent(); + WriteLine("{0}(true);", destroyNativeInstance); + WriteCloseBraceIndent(); + NewLine(); + + WriteLine("private void {0}(bool force)", destroyNativeInstance); + WriteStartBraceIndent(); if (@class.IsRefType) { @@ -1790,7 +1805,8 @@ namespace CppSharp.Generators.CSharp if (!Options.CheckSymbols || Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library)) { - WriteLine("Internal.{0}({1});", GetFunctionNativeIdentifier(dtor), + WriteLine("if ({0} || force)", Helpers.OwnsNativeInstanceIdentifier); + WriteLineIndent("Internal.{0}({1});", GetFunctionNativeIdentifier(dtor), Helpers.InstanceIdentifier); } } @@ -1799,14 +1815,9 @@ namespace CppSharp.Generators.CSharp if (@class.IsRefType) { WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier); - WriteStartBraceIndent(); - WriteLine("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier); - WriteCloseBraceIndent(); + WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier); } - if (hasBaseClass) - WriteLine("base.Dispose(disposing);"); - WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); } diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index 4ee90888..74471972 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -239,4 +239,18 @@ public class CSharpTempTests : GeneratorTestFixture Assert.IsFalse(Bar.NativeToManagedMap.ContainsKey(bar.__Instance)); } } + + [Test] + public void TestNotDestroyingForeignObjects() + { + using (var testNativeToManagedMap = new TestNativeToManagedMap()) + { + var hasVirtualDtor2 = testNativeToManagedMap.HasVirtualDtor2; + hasVirtualDtor2.Dispose(); + using (var hasVirtualDtor1 = hasVirtualDtor2.HasVirtualDtor1) + { + Assert.AreEqual(5, hasVirtualDtor1.TestField); + } + } + } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index 9f7ebda3..0edf818b 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -401,6 +401,11 @@ Foo StructWithPrivateFields::getComplexPrivateField() return complexPrivateField; } +HasVirtualDtor1::HasVirtualDtor1() +{ + testField = 5; +} + HasVirtualDtor1::~HasVirtualDtor1() { } diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 207f00de..21f438f4 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -427,7 +427,9 @@ void TestPointers::TestTripleCharPointers(const char*** names) class DLL_API HasVirtualDtor1 { public: + HasVirtualDtor1(); virtual ~HasVirtualDtor1(); + int testField; }; class DLL_API HasVirtualDtor2