Browse Source

Forbid the disposal of unowned objects and simplified the generated code.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/553/head
Dimitar Dobrev 10 years ago
parent
commit
5dca339ff2
  1. 61
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 9
      tests/CSharp/CSharp.Tests.cs

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

@ -1475,7 +1475,7 @@ namespace CppSharp.Generators.CSharp @@ -1475,7 +1475,7 @@ namespace CppSharp.Generators.CSharp
{
if (method.IsDestructor)
{
WriteLine("{0}.DestroyNativeInstance();", Helpers.TargetIdentifier);
WriteLine("{0}.Dispose(false);", Helpers.TargetIdentifier);
return;
}
@ -1784,11 +1784,14 @@ namespace CppSharp.Generators.CSharp @@ -1784,11 +1784,14 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType)
{
GenerateClassFinalizer(@class);
GenerateDisposeMethods(@class);
// Only root bases need a Dispose
if (ShouldGenerateClassNativeField(@class))
GenerateDisposeMethods(@class);
}
}
private void GenerateClassFinalizer(Class @class)
private void GenerateClassFinalizer(INamedDecl @class)
{
if (!Options.GenerateFinalizers)
return;
@ -1836,21 +1839,9 @@ namespace CppSharp.Generators.CSharp @@ -1836,21 +1839,9 @@ 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 {0} void {1}()", hasBaseClass ? "override" : "virtual", destroyNativeInstance);
WriteStartBraceIndent();
WriteLine("{0}(true);", destroyNativeInstance);
WriteCloseBraceIndent();
NewLine();
WriteLine("private void {0}(bool force)", destroyNativeInstance);
WriteStartBraceIndent();
WriteLine("if (!{0} && disposing)", Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("throw new global::System.InvalidOperationException" +
"(\"Managed instances owned by native code cannot be disposed of.\");");
if (@class.IsRefType)
{
@ -1878,34 +1869,22 @@ namespace CppSharp.Generators.CSharp @@ -1878,34 +1869,22 @@ namespace CppSharp.Generators.CSharp
}
var dtor = @class.Destructors.FirstOrDefault();
if (ShouldGenerateClassNativeField(@class))
if (dtor != null && dtor.Access != AccessSpecifier.Private &&
@class.HasNonTrivialDestructor && !dtor.IsPure)
{
if (dtor != null && dtor.Access != AccessSpecifier.Private &&
@class.HasNonTrivialDestructor && !dtor.IsPure)
NativeLibrary library;
if (!Options.CheckSymbols ||
Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library))
{
NativeLibrary library;
if (!Options.CheckSymbols ||
Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library))
{
WriteLine("if ({0} || force)", Helpers.OwnsNativeInstanceIdentifier);
if (dtor.IsVirtual)
{
WriteStartBraceIndent();
GenerateVirtualFunctionCall(dtor, @class);
WriteCloseBraceIndent();
}
else
{
GenerateInternalFunctionCall(dtor);
}
}
if (dtor.IsVirtual)
GenerateVirtualFunctionCall(dtor, @class);
else
GenerateInternalFunctionCall(dtor);
}
WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
}
WriteLine("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
}

9
tests/CSharp/CSharp.Tests.cs

@ -311,11 +311,10 @@ public class CSharpTests : GeneratorTestFixture @@ -311,11 +311,10 @@ public class CSharpTests : GeneratorTestFixture
using (var testNativeToManagedMap = new TestNativeToManagedMap())
{
var hasVirtualDtor2 = testNativeToManagedMap.HasVirtualDtor2;
hasVirtualDtor2.Dispose();
using (var hasVirtualDtor1 = hasVirtualDtor2.HasVirtualDtor1)
{
Assert.AreEqual(5, hasVirtualDtor1.TestField);
}
Assert.Catch<InvalidOperationException>(hasVirtualDtor2.Dispose);
var hasVirtualDtor1 = hasVirtualDtor2.HasVirtualDtor1;
Assert.AreEqual(5, hasVirtualDtor1.TestField);
Assert.Catch<InvalidOperationException>(hasVirtualDtor1.Dispose);
}
}

Loading…
Cancel
Save