Browse Source

Prevented Dispose from destroying unmanaged objects we didn't create.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/461/head
Dimitar Dobrev 10 years ago
parent
commit
7328538f19
  1. 25
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 14
      tests/CSharpTemp/CSharpTemp.Tests.cs
  3. 5
      tests/CSharpTemp/CSharpTemp.cpp
  4. 2
      tests/CSharpTemp/CSharpTemp.h

25
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -1766,6 +1766,21 @@ namespace CppSharp.Generators.CSharp
WriteLine("void Dispose(bool disposing)"); WriteLine("void Dispose(bool disposing)");
WriteStartBraceIndent(); 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) if (@class.IsRefType)
{ {
@ -1790,7 +1805,8 @@ namespace CppSharp.Generators.CSharp
if (!Options.CheckSymbols || if (!Options.CheckSymbols ||
Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library)) 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); Helpers.InstanceIdentifier);
} }
} }
@ -1799,14 +1815,9 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType) if (@class.IsRefType)
{ {
WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier); WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier);
WriteStartBraceIndent(); WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
WriteLine("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
WriteCloseBraceIndent();
} }
if (hasBaseClass)
WriteLine("base.Dispose(disposing);");
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }

14
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -239,4 +239,18 @@ public class CSharpTempTests : GeneratorTestFixture
Assert.IsFalse(Bar.NativeToManagedMap.ContainsKey(bar.__Instance)); 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);
}
}
}
} }

5
tests/CSharpTemp/CSharpTemp.cpp

@ -401,6 +401,11 @@ Foo StructWithPrivateFields::getComplexPrivateField()
return complexPrivateField; return complexPrivateField;
} }
HasVirtualDtor1::HasVirtualDtor1()
{
testField = 5;
}
HasVirtualDtor1::~HasVirtualDtor1() HasVirtualDtor1::~HasVirtualDtor1()
{ {
} }

2
tests/CSharpTemp/CSharpTemp.h

@ -427,7 +427,9 @@ void TestPointers::TestTripleCharPointers(const char*** names)
class DLL_API HasVirtualDtor1 class DLL_API HasVirtualDtor1
{ {
public: public:
HasVirtualDtor1();
virtual ~HasVirtualDtor1(); virtual ~HasVirtualDtor1();
int testField;
}; };
class DLL_API HasVirtualDtor2 class DLL_API HasVirtualDtor2

Loading…
Cancel
Save