Browse Source

Free the memory of the patched v-tables

Fixes https://github.com/mono/CppSharp/issues/586.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
const-wchar_t
Dimitar Dobrev 5 years ago
parent
commit
076318be29
  1. 7
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 28
      src/Runtime/SafeUnmanagedMemoryHandle.cs

7
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1528,6 +1528,11 @@ namespace CppSharp.Generators.CSharp
NewLine(); NewLine();
GenerateVTableClassSetup(@class, wrappedEntries); GenerateVTableClassSetup(@class, wrappedEntries);
WriteLine("private static readonly global::System.Collections.Generic.List<" +
"global::CppSharp.Runtime.SafeUnmanagedMemoryHandle> __handleManagedVTables" +
" = new global::System.Collections.Generic.List<" +
"global::CppSharp.Runtime.SafeUnmanagedMemoryHandle>();");
NewLine();
WriteLine("#endregion"); WriteLine("#endregion");
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
@ -1638,6 +1643,7 @@ namespace CppSharp.Generators.CSharp
string vfptr = $"vfptr{(destructorOnly ? "_dtor" : string.Empty)}{i}"; string vfptr = $"vfptr{(destructorOnly ? "_dtor" : string.Empty)}{i}";
WriteLine($@"var {vfptr} = Marshal.AllocHGlobal({size} * { WriteLine($@"var {vfptr} = Marshal.AllocHGlobal({size} * {
Context.TargetInfo.PointerWidth / 8});"); Context.TargetInfo.PointerWidth / 8});");
WriteLine($"__handleManagedVTables.Add(new global::CppSharp.Runtime.SafeUnmanagedMemoryHandle({vfptr}, true));");
WriteLine($"{managedVTables}[{i}] = {vfptr}.ToPointer();"); WriteLine($"{managedVTables}[{i}] = {vfptr}.ToPointer();");
AllocateNewVTableEntries(vftable.Layout.Components, wrappedEntries, AllocateNewVTableEntries(vftable.Layout.Components, wrappedEntries,
@ -1655,6 +1661,7 @@ namespace CppSharp.Generators.CSharp
int size = @class.Layout.Layout.Components.Count; int size = @class.Layout.Layout.Components.Count;
uint pointerSize = Context.TargetInfo.PointerWidth / 8; uint pointerSize = Context.TargetInfo.PointerWidth / 8;
WriteLine($"var vtptr{suffix} = Marshal.AllocHGlobal({size} * {pointerSize});"); WriteLine($"var vtptr{suffix} = Marshal.AllocHGlobal({size} * {pointerSize});");
WriteLine($"__handleManagedVTables.Add(new global::CppSharp.Runtime.SafeUnmanagedMemoryHandle(vtptr{suffix}, true));");
WriteLine($@"var vfptr{suffix}0 = vtptr{suffix} + { WriteLine($@"var vfptr{suffix}0 = vtptr{suffix} + {
VTables.ItaniumOffsetToTopAndRTTI} * {pointerSize};"); VTables.ItaniumOffsetToTopAndRTTI} * {pointerSize};");

28
src/Runtime/SafeUnmanagedMemoryHandle.cs

@ -0,0 +1,28 @@
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
namespace CppSharp.Runtime
{
// https://stackoverflow.com/a/17563315/
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
public sealed class SafeUnmanagedMemoryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeUnmanagedMemoryHandle() : base(true) { }
public SafeUnmanagedMemoryHandle(IntPtr preexistingHandle, bool ownsHandle)
: base(ownsHandle) => SetHandle(preexistingHandle);
protected override bool ReleaseHandle()
{
if (handle != IntPtr.Zero)
{
Marshal.FreeHGlobal(handle);
handle = IntPtr.Zero;
return true;
}
return false;
}
}
}
Loading…
Cancel
Save