Ограничения против абстрактного класса с использованием SafeHandle
В BCryptNative есть метод GetInt32Property. Имеет следующую подпись:
internal static int GetInt32Property<T>(T algorithm, string property) where T : SafeHandle
Этот метод работает, только когда T имеет тип SafeBCryptAlgorithmHandle или SafeBCryptHashHandle. Он вызывает собственные методы, которые явно определены с этими типами дескрипторов:
[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetAlgorithmProperty(SafeBCryptAlgorithmHandle hObject,
string pszProperty,
[MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
int cbOutput,
[In, Out] ref int pcbResult,
int flags);
[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetHashProperty(SafeBCryptHashHandle hObject,
string pszProperty,
[MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
int cbOutput,
[In, Out] ref int pcbResult,
int flags);
Microsoft использует указатели / делегаты функций для указания на правильную нативную функцию. Мой вопрос: почему Microsoft не реализовала метод GetInt32Property со следующей подписью:
internal static int GetInt32Property(SafeHandle algorithm, string property)
с помощью следующего собственного метода:
[DllImport("bcrypt.dll", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetProperty(SafeHandle hObject,
string pszProperty,
[MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
int cbOutput,
[In, Out] ref int pcbResult,
int flags);
Есть ли минусы в этом? (при условии, что SafeHandle, переданный в GetInt32Property, всегда является либо SafeBCryptAlgorithmHandle, либо SafeBCryptHashHandle).
Мне просто интересно, почему Microsoft реализовала это так относительно сложно.
Это должно с:
- Безопасность-Прозрачный код?
- Типа безопасности? (Так что вы никогда не используете ничего, кроме этих двух типов)
- Разрешено ли использовать SafeHandle явно?
Согласно документации, класс должен быть унаследован, и, тем не менее, правильно ли обрабатывает функция P/Invoked, когда ему предоставляется абстрактный класс SafeHandle? Это увеличивает и уменьшает счетчик ссылок соответственно?
1 ответ
Трудно сказать, почему Microsoft решила реализовать что-то так или иначе, но я могу ответить на ваши вопросы.
- Код не сложный. Использование понятно (что-то вроде
GetInt32Property(algorithm, str)
, - Это не заставляет вас отправлять один из упомянутых вами типов, вы все равно можете вызывать его с другим классом, если он реализует
SafeHandle
, - Используемые нативные методы фактически одинаковы. Это немного странно, но я не специалист по этой конкретной библиотеке, так что это может быть веской причиной.
- Существует скрытая выгода для общих методов, таких как этот.
typeof(T) == typeof(SafeBCryptHashHandle)
проверки типов выполняются не во время выполнения, а во время JIT. Это означает, что метод должен выполняться немного быстрее, чем обычная проверка во время выполнения, напримерalgorith is SafeBCrypthHashHandle
,
SafeHandle
класс это абстрактный класс. Это означает, что вы не можете создать его экземпляр, но можете наследовать его. Нативная функция получает только маршалированные данные, но не дает реальных ссылок на объекты. Не беспокойтесь о подсчете ссылок.