Как правильно выпустить SafeHandleZeroOrMinusOneIsInvalid или SafeHandle?

1

Я прочитал некоторую документацию, и вот класс, я использую для операций IntPtr, чтобы сделать их более безопасными:

internal class MySafeHandleOperator : SafeHandleZeroOrMinusOneIsInvalid
{
    public MySafeHandleOperator(IntPtr handle) : base(true)
    {
        SetHandle(handle);
    }

    public IntPtr GetPtr()
    {
        return this.handle;
    }

    protected override bool ReleaseHandle()
    {
        this.Dispose(true);
        return true;
    }
}

Главный вопрос - в методе ReleaseHandle. Я использовал его таким образом, но я убежден, если это правильный способ использования? Может быть, есть еще один, правильный способ выпустить дескриптор и очистить этот класс?

Я хотел бы использовать этот класс аналогично (простой пример):

Process p = Process.Start(processName);
MySafeHandleOperator mh = new MySafeHandleOperator(p.MainWindowHandle);

Был бы признателен, если бы кто-то взглянул и сказал, если я все сделаю правильно, или этот метод нужно переадресовать.

  • 0
    Вы наследуете от SafeHandleZeroOrMinusOneIsInvalid чтобы убедиться, что дескрипторы правильно закрыты, например, с помощью CloseHandle . HWND не такая ручка. Вам не нужно наследовать от класса safehandle, чтобы передать его. Если бы это был такой тип дескриптора, вы бы CloseHandle(this.handle) из ReleaseHandle . Не пытайтесь избавиться от объекта оттуда.
Теги:
handle
unmanaged
intptr

1 ответ

4

Нет, это не выглядит хорошо. Пункт SafeHandle состоит в том, чтобы гарантировать, что ваш объект класса не будет уничтожен, пока вы передадите дескриптор на собственный код. Это может быть неприятно, ваш финализатор вызывается, а собственный код продолжает использовать недопустимый дескриптор. Помимо сбоев во время выполнения и коррупции, которые могут вызывать, существует также очень страшный сценарий атаки на перезагрузку дескриптора, который активируется этим.

Однако у вас нет абсолютно никакого контроля над временем работы этого дескриптора окна. Вы не можете остановить его от разрушения и не можете ничего сделать, чтобы уничтожить его самостоятельно. Ну, предполагая, что вы не собираетесь убивать процесс с помощью финализатора. Что-то, что вы могли обнаружить, не имея полезного переопределения для ReleaseHandle(). Используйте, скажем, класс SafeFileHandle в качестве примера практического производного класса. У.NET Framework много, хороший декомпилятор - отличный способ найти их.

Короче говоря, поскольку нет смысла обертывать его, IntPtr в порядке

  • 0
    Итак, насколько я понимаю, нет необходимости работать с этим классом с простыми оконными ресурсами, возвращая IntPtr. И единственный разумный способ его использования - это иметь некоторые ресурсы, которые я сам контролирую
  • 1
    Этот код был фактически вдохновлен blog.benoitblanchon.fr/safehandle . В чем разница между этим и этим кодом при вызове неуправляемых функций?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню