代码之家  ›  专栏  ›  技术社区  ›  hl3mukkel

约束与使用SafeHandle的抽象类

  •  3
  • hl3mukkel  · 技术社区  · 9 年前

    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);
    

    这有什么缺点吗?(假设传递给GetInt32Property的SafeHandle总是 SafeBCryptoAlgorithmHandle SafeBCryptHashHandle ).

    我只是想知道为什么微软实现了这一相对复杂的功能。

    是否必须与:

    • 安全透明代码?
    • 类型安全?(因此,除了这两种类型之外,您永远不会使用其他类型)
    • 是否允许显式使用SafeHandle?

    根据 documentation 类必须是继承的,但当给定SafeHandle的抽象类时,P/Invoked函数是否正确处理它?它是否适当地增加和减少参考计数?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Mark Segal    9 年前

    很难说微软为什么选择以这样或那样的方式实现某些东西,但我可以回答你的观点。

    • 代码并不复杂。用法很清楚(类似 GetInt32Property(algorithm, str) .
    • 它不会强制您发送您提到的类型之一,您仍然可以使用不同的类调用它,只要它实现 SafeHandle .
    • 使用的本机方法实际上是相同的。这有点奇怪,但我不是这个特定库的专家,所以这可能是有原因的。
    • 像这样的泛型方法有一个隐藏的好处。这个 typeof(T) == typeof(SafeBCryptHashHandle) 类型检查不是在运行时进行的,而是在JIT时间进行的。这意味着该方法的执行速度应该稍快于常规运行时检查,如 algorith is SafeBCrypthHashHandle .

    这个 安全手柄 类是一个抽象类。这意味着不能创建它的实例,但可以继承它。本机函数只获取封送数据,而不获取对象的实际引用。不要担心引用计数。