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. 39
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 7
      tests/CSharp/CSharp.Tests.cs

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

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

7
tests/CSharp/CSharp.Tests.cs

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

Loading…
Cancel
Save