Top / .NET備忘録 / 14.【注意】VarPtr関数 / 01.注意点をふまえた上で実装

GCHandle.Alloc したものをどこで Free するか問題になるわけですが、VarPtr 関数の中で Free するのは少し危険です。

めったにあることではありませんが Free した瞬間、取得したアドレスが無効になってしまう可能性があるからです。

SafeHandle を継承したクラスを作成し、そのクラスが回収されたときに Free されるようにします。

VarPtr はそのクラスを返します。

using System;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic.CompilerServices;

namespace VB6Control
{
    [StandardModule]
    public class _HiddenModule
    {
        public static GCSafeHandle ObjPtr<T>(T obj)
            where T : class {
            return new GCSafeHandle(obj);
        }

        public static GCSafeHandle VarPtr<T>(ref T obj)
            where T : struct {
            return new GCSafeHandle(obj);
        }

        public static GCSafeHandle StrPtr(string str) {
            return new GCSafeHandle(str);
        }
    }

    public class GCSafeHandle : SafeHandle
    {
        GCHandle _GCHandle;

        internal GCSafeHandle(object obj)
            : base(IntPtr.Zero, true) {
            _GCHandle = GCHandle.Alloc(obj, GCHandleType.Pinned);
            base.SetHandle(_GCHandle.AddrOfPinnedObject());
        }

        public override bool IsInvalid {
            get {
                return !_GCHandle.IsAllocated;
            }
        }

        protected override bool ReleaseHandle() {
            _GCHandle.Free();
            return true;
        }

        public object Target {
            get {
                return _GCHandle.Target;
            }
        }
    }
}



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2017-05-19 (金) 10:16:24 (90d)