使用 SafeHandle 的约束与抽象 class
Constraints vs abstract class using SafeHandle
BCryptNative 中有一个名为 GetInt32Property 的方法。
它具有以下签名:
internal static int GetInt32Property<T>(T algorithm, string property) where T : SafeHandle
此方法仅在T为SafeBCryptAlgorithmHandle or 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);
这有什么缺点吗? (假设传递给 GetInt32Property 的 SafeHandle 总是 SafeBCryptAlgorithmHandle or SafeBCryptHashHandle)。
我只是想知道为什么微软实现这个相对复杂。
是否必须与:
- 安全透明代码?
- 类型安全? (这样你就不会使用这两种类型以外的任何其他类型)
- 是否允许显式使用 SafeHandle?
根据 documentation,class 必须被继承,但是 P/Invoked 函数在给定 SafeHandle 的抽象 class 时是否正确处理它?它是否适当地增加和减少引用计数?
很难说出微软为什么选择以这种或那种方式实现某些东西,但我可以回答你的观点。
- 代码并不复杂。用法很清楚(类似于
GetInt32Property(algorithm, str)
.
- 它不会强制你发送你提到的类型之一,你仍然可以用不同的 class 调用它,只要它实现
SafeHandle
.
- 使用的native方法其实都是一样的。这有点奇怪,但我不是这个特定库的专家,所以这可能是有充分理由的。
- 像这样的通用方法有一个隐藏的好处。
typeof(T) == typeof(SafeBCryptHashHandle)
类型检查不是在运行时完成的,而是在 JIT 时间完成的。这意味着该方法的执行速度应该比 algorith is SafeBCrypthHashHandle
. 等常规运行时检查稍快
SafeHandle
class 是一个摘要class。这意味着您不能创建它的实例,但可以继承它。本机函数仅获取编组数据,它们不会获取对对象的真实引用。不用担心引用计数。
BCryptNative 中有一个名为 GetInt32Property 的方法。 它具有以下签名:
internal static int GetInt32Property<T>(T algorithm, string property) where T : SafeHandle
此方法仅在T为SafeBCryptAlgorithmHandle or 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);
这有什么缺点吗? (假设传递给 GetInt32Property 的 SafeHandle 总是 SafeBCryptAlgorithmHandle or SafeBCryptHashHandle)。
我只是想知道为什么微软实现这个相对复杂。
是否必须与:
- 安全透明代码?
- 类型安全? (这样你就不会使用这两种类型以外的任何其他类型)
- 是否允许显式使用 SafeHandle?
根据 documentation,class 必须被继承,但是 P/Invoked 函数在给定 SafeHandle 的抽象 class 时是否正确处理它?它是否适当地增加和减少引用计数?
很难说出微软为什么选择以这种或那种方式实现某些东西,但我可以回答你的观点。
- 代码并不复杂。用法很清楚(类似于
GetInt32Property(algorithm, str)
. - 它不会强制你发送你提到的类型之一,你仍然可以用不同的 class 调用它,只要它实现
SafeHandle
. - 使用的native方法其实都是一样的。这有点奇怪,但我不是这个特定库的专家,所以这可能是有充分理由的。
- 像这样的通用方法有一个隐藏的好处。
typeof(T) == typeof(SafeBCryptHashHandle)
类型检查不是在运行时完成的,而是在 JIT 时间完成的。这意味着该方法的执行速度应该比algorith is SafeBCrypthHashHandle
. 等常规运行时检查稍快
SafeHandle
class 是一个摘要class。这意味着您不能创建它的实例,但可以继承它。本机函数仅获取编组数据,它们不会获取对对象的真实引用。不用担心引用计数。