f# - 在 F# 中使用安全句柄

标签 f# safehandle

我正在处理一些使用平台调用的 F# 代码。我正在使用的 API 之一返回一个句柄。我没有使用 nativeint,而是实现了自己的 SafeHandle(特别是 SafeHandleMinusOneIsInvalid)。这使得使用包含 pinvoke 签名的模块有点笨拙。这是一个例子:

type MySafeHandle() = 
    inherit SafeHandleZeroOrMinusOneIsInvalid(true)

    override this.ReleaseHandle() =
        NativeMethods.FreeHandle(base.handle)            
        true

module NativeMethods = 
    [<DllImport("mylibrary.dll")>]
    extern void GetHandle([<Out>]MySafeHandle& handle)
    [<DllImport("mylibrary.dll")>]
    extern void FreeHandle(nativeint handle)

这不会编译,因为模块和类递归地相互引用,这是行不通的。如果我将模块移至 MySafeHandle 上方,则 GetHandle 将看不到 SafeHandle。

我无法在 MySafeHandle 中移动平台调用方法,因为在 F# must be in modules 中似乎有外部方法(即使编译器不会阻止您尝试将它们放入类中)。

似乎 F# 的 recursive types不要在模块和类之间工作,只能在类之间工作。

是否有不需要声明两个不同模块的解决方案?理想情况下,我希望将所有平台调用代码组织到一个模块中。

最佳答案

嗯,我知道一个,因为我自己也遇到过同样的问题。

问题是,我猜它有点丑:

它涉及您稍后在模块中设置为导入函数的静态引用。

type MySafeHandle() = 
    inherit SafeHandleZeroOrMinusOneIsInvalid(true)
    static let freeHandle = ref Unchecked.defaultof<_>
    static member internal SetFreeHandleRef value = freeHandle := value

    override this.ReleaseHandle() =
        !freeHandle base.handle            
        true

module NativeMethods = 
    [<DllImport("mylibrary.dll")>]
    extern void GetHandle([<Out>]MySafeHandle& handle)
    [<DllImport("mylibrary.dll")>]
    extern void FreeHandle(nativeint handle)

    MySafeHandle.SetFreeHandleRef FreeHandle

关于f# - 在 F# 中使用安全句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25004314/

相关文章:

f# - FSI 对程序集保持独占锁定

c# - DllImport - C 类型到 .NET 类型

f# - 用计算表达式附加多个列表

c# - SafeHandle 中 invalidHandleValue 的用途是什么?

c# - 如何正确处理 pinvoke/非托管代码

c# - 错误 : a SafeHandle or CriticalHandle of type ZLibStreamHandle failed to properly release

c# - 如何防止同一个非托管指针被封装在两个不同的 SafeHandles 中?

c# - C++ 到 .NET : I need help with understanding C++ code to convert it to . NET

f# - 有没有更好的方法在 F# 中编写命名管道?