Какие разновидности IntPtr являются кандидатами на участие в SafeHandle?

Я получаю CA2006 ("Review usage of ... (a 'IntPtr' instance) to determine whether it should be replaced with a SafeHandle or CriticalHandle") для IntPtr вернулся из ConvertStringSecurityDescriptorToSecurityDescriptor я знаю, что это дескриптор безопасности, который может быть освобожден с FreeLocal, Я использую это только кратко и, вероятно, не теряю вовлеченную память. Насколько я могу судить, дескриптор ядра не связан.

Есть много SafeHandle подклассы и ни один из них, кажется, не вызывает FreeLocal в конце жизни обернутого объекта. Тем не менее, я не могу найти какую-либо определенную информацию о том, какие IntPtr экземпляры (скажем, возвращаемые Win32 API) эффективно управляются SafeHandle а какие нет.

Должен ли я просто подавить предупреждение CA?

Что более важно, как определить то же самое для следующего IntPtr использование я столкнусь?

(Таблица, которая будет отображать SafeHandle подклассы к функциям, которые в конечном итоге освободят дескриптор, были бы великолепны

1 ответ

Решение

Если ваш вопрос "уже есть SafeHandle подкласс, который вызывает LocalFree освободить свою ручку ", то да, есть - это SafeLocalAllocHandle, Класс internal, поэтому он не доступен для широкой публики, но код очевиден, если вы хотите воссоздать его. Если ваш вопрос "должен ли я использовать такой класс", ну, это своего рода суждение. CA2006 и SafeHandle Документация объясняет обоснование конструкции: SafeHandle избегает проблем с повторным использованием дескрипторов в многопоточных сценариях и имеет специальную поддержку P/Invokes, чтобы гарантировать, что дескрипторы не будут случайно освобождены до того, как с ними будет сделан неуправляемый код

Когда это IntPtr ручка, которая может быть обернута SafeHandle? Вы не сможете сказать от IntPtr, вы должны знать, какая функция возвращает IntPtr, Он документирует, имеете ли вы дело с дескриптором и, если да, как вы должны закрыть дескриптор, когда закончите с ним (очень часто, но далеко не всегда, CloseHandle). Если у вас есть только подпись P / Invoke, то технически у вас ничего нет. В частности, будет невозможно определить, какую функцию следует вызывать для освобождения дескриптора, если он является дескриптором. IntPtr также может быть использован для маршала PVOID или же SIZE_T или же P<some_struct> (даже если out или же ref параметры более естественные для этого) или любой другой тип, который должен иметь размер указателя.

Любая ручка как IntPtr которая выходит за пределы одной функции (особенно той, которая хранится в поле) - действительно хороший кандидат на SafeHandle обертка, как и любое использование нескольких IntPtr s одновременно (для предотвращения случайного замешивания несовместимых ручек). Для простого одноразового использования, не требующего многопоточности и не позволяющего дескриптору выйти за пределы его возможностей, try .. finally блока, наверное, достаточно. Если хотите, все можно завернуть в SafeHandle для согласованности (или для явного документирования того, с каким типом объекта вы имеете дело), ​​но это не обязательно приводит к лучшим результатам. Повторное использование дескриптора - серьезная проблема, но здесь это не касается, поскольку дескриптор относится к локальной памяти, а надежность - не проблема, потому что любая проблема достаточно серьезна, чтобы обойти finally Блок также достаточно серьезен, чтобы небольшая утечка памяти не стала проблемой.

Ваш конкретный сценарий (анализ SDDL в дескриптор безопасности) уже реализован в рамках в виде RawSecurityDescriptor, который вы должны рассмотреть в пользу переизобретения колеса (и / или реализации своего собственного SecurityDescriptor подкласс, если он еще не охвачен существующими классами в System.Security.AccessControl, Для чего это стоит, RawSecurityDescriptor также P / Призывает к ConvertStringSecurityDescriptorToSecurityDescriptorW и не беспокоит с SafeHandle, Фреймворковый код не обязательно должен рассматриваться как хороший пример того, что нужно делать (большое количество кода нарушает официальные правила), но это нечто.

Другие вопросы по тегам