繁体   English   中英

在F#中使用SafeHandles

[英]Working with SafeHandles in F#

我正在使用一些使用平台调用的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#中的extern方法必须在模块中 (即使编译器不会阻止您尝试将它们放在类中)。

似乎F#的递归类型在模块和类之间不起作用,只是类。

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

我知道一个,因为我自己也有同样的问题。

问题是,我觉得它有点难看:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM